Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře

AM

Citace od: g52 kdy 14. 12. 2021, 18:14:05
Ahoj, neporadil by mi někdo jak dostat do cyklu všechny názvy souborů z daného adresáře (bez cesty) pro níže uvedenou verzi bash? Díky


for id in $(find ~/cesta -printf '%f\n')
do
   ...
done



Dostanu chybu:
find: -printf: unknown primary or operator


bash --version
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin21)
Copyright (C) 2007 Free Software Foundation, Inc.

Pod macOS je starý find, který nemá tolik možností jako GNU find. Řešením je použít volby -print nebo -print0 a adresáře z cesty odstranit v cyklu příkazem basename. Tenhle příkaz v macOS je.

Pokud vím, tak Bash napřed vyhodnotí ten příkaz $(find ), takže tahle technika je vhodná pro menší počet souborů. V opačném případě je lepší nechat find ten výstup posílat do roury, jak zde lidé navrhují.

Také je třeba vědět, jak se ten skript bude chovat, když jména budou obsahovat mezery nebo techniky "command injection".


k3dAR

  • *****
  • 3 193
Citace od: g52 kdy 14. 12. 2021, 23:01:17
Citace od: k3dAR kdy 14. 12. 2021, 22:18:15
duvod proc ti to tvoje nejde je v podstate ten, ze zpracovavas vystup pres pipe, jehoz promene se ale nasledne ztraci ;-) bez pipe se to dela takto:
#!/bin/bash

ARR=()
while read fn
do
   ARR+=("$fn")
done < <(find ~/cesta)

echo ${#ARR[@]}


Dostanu chybu
syntax error near unexpected token `<'
`done < <(find ~/data_dir)'


PS: pipe je ten použitý znak '|'?

nemam po ruce starej bash na overeni, co tohle?

#!/bin/bash

ARR=()
while read fn
do
   ARR+=("$fn")
done <<< "$(find ~/cesta)"

echo ${#ARR[@]}


ano znak "|" je pipe/roura

Nevymyslite kolo?
Mne to funguje takto:

for i in $(find . -type f -print); do
basename $i
done

...a mam vsechny soubory od aktualniho adresare nize, jen jejich jmena.

Bob

Citace od: Bob Sinclair kdy 15. 12. 2021, 12:08:32
for i in $(find . -type f -print); do
basename $i
done

Jednoduchšie (a stále funkčné :)) je

find . -type f -exec basename {} \;

jvb

Citace od: Ignotus kdy 15. 12. 2021, 14:59:19
Citace od: Bob Sinclair kdy 15. 12. 2021, 12:08:32
for i in $(find . -type f -print); do
basename $i
done

Jednoduchšie (a stále funkčné :)) je

find . -type f -exec basename {} \;

Nabo si nainstalovat prikaz tree a pouzit neco jako
tree -i