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

AM

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


Kód: [Vybrat]
for id in $(find ~/cesta -printf '%f\n')
do
   ...
done

Kód: [Vybrat]
Dostanu chybu:
find: -printf: unknown primary or operator

Kód: [Vybrat]
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

  • *****
  • 2 838
  • porad nemam telo, ale uz mam hlavu... nobody
    • Zobrazit profil
    • E-mail
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:
Kód: [Vybrat]
#!/bin/bash

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

echo ${#ARR[@]}

Dostanu chybu
Kód: [Vybrat]
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?

Kód: [Vybrat]
#!/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

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

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

Kód: [Vybrat]
find . -type f -exec basename {} \;

jvb

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

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

Kód: [Vybrat]
find . -type f -exec basename {} \;

Nabo si nainstalovat prikaz tree a pouzit neco jako
Kód: [Vybrat]
tree -i