Fórum Root.cz

Hlavní témata => Server => Téma založeno: g52 14. 12. 2021, 18:14:05

Název: Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 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


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.
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: mhi 14. 12. 2021, 18:27:09
pouzivam kvuli mezeram a paznakum obvykle toto
find .  ... |while read fn ; do echo "zpracovavam soubor $fn" ; done
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 19:36:42
Díky ale nějak to nešlape. Myslel jsi to takto?

Kód: [Vybrat]
VAR=""
find ~/cesta | while read fn
do
   VAR+=$fn
   echo $fn
done

echo $VAR

# echo $fn vypíše všechny položky ale proměnná VAR je prázdná
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: mhi 14. 12. 2021, 20:00:35
nerozumim tomu ceho chcete dosahnout, v tom 'do' cyklu muzete soubory zpracovat. jestli to chcete do jedne promenne, jde dat

VAR=`find .`

a je to :). Jenze jakmile tam bude mezera nebo nejaky paznak, bude to bezcenna zmet znaku.

Pricitani obvykle delam VAR="$VAR $fn" nebo neco na ten zpusob. Operator += nepouzivam, mozna tam maji byt mezery, nevim.
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 20:24:28
Blbě jsem to napsal. mělo to být pole ne string, ale to je jedno, pole se nenaplní a nevím proč.

Kód: [Vybrat]
ARR=()
find ~/cesta | while read fn
do
   ARR+=("$fn")
done
echo ${#ARR[@]} RESULT = 0

Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: M Z 14. 12. 2021, 20:29:52
Proc tak slozite?  ;)
Kód: [Vybrat]
find ~/cesta  | while read line; do
blablabla "$line"
done
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: registrovany123 14. 12. 2021, 20:48:28
Tak to ti reknu naprosto presne, jsem kovany bashista a nedam na nej dopustit, jiz od starych dob se to dela takto:

Kód: [Vybrat]
#!/bin/bash

python3 -m udelej.py
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: M Z 14. 12. 2021, 21:11:36
Pobavilo, ale ja to radeji resim vice old school:
Kód: [Vybrat]
find dir -print0 | awk  -f prog.awk  #a v prog.awk RS="\0"
Ale funguje to jen s gawk.
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 22:00:20
Proc tak slozite?  ;)
Kód: [Vybrat]
find ~/cesta  | while read line; do
blablabla "$line"
done

Tohle vypadá že funguje, ale musím to pořádně otestovat, díky
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 22:03:01
Tak to ti reknu naprosto presne, jsem kovany bashista a nedam na nej dopustit, jiz od starych dob se to dela takto:

Kód: [Vybrat]
#!/bin/bash

python3 -m udelej.py

python mám rád, ale dělám aplikaci ve které potřebuji získat stisk kláves, což je problém, žádná knihovna která je nainstalovaná v systému kromě curses to neumí.
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 22:16:51
Proc tak slozite?  ;)
Kód: [Vybrat]
find ~/cesta  | while read line; do
blablabla "$line"
done

Tohle vypadá že funguje, ale musím to pořádně otestovat, díky

Tak ne, radost byla předčasná, pokud naplním proměnou STR v tom cyklu, mimo cyklus je zase prázdná :(

Kód: [Vybrat]
find ~/cesta  | while read line; do
STR="$line"
done
echo $STR # proměnná je prázdná
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: k3dAR 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:
Kód: [Vybrat]
#!/bin/bash

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

echo ${#ARR[@]}
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: g52 14. 12. 2021, 23:01:17
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 '|'?
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: M Z 14. 12. 2021, 23:39:19
Myslim ze tohle presmerovani < <() ve starsich verzich Bash nefungovalo. Zkus to s tmp souborem
Kód: [Vybrat]
find ~/data_dir >/tmp/$$.out
while read line; do
...
done </tmp/$$.out
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: Google CTCCTCGGCGGGCACGTAG 15. 12. 2021, 00:33:32
GNU Parallel

Kód: [Vybrat]
#!/bin/bash
body(){
    echo $1
}
export -f body
find . | parallel -P 1 body {}
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: AM 15. 12. 2021, 10:40:28
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".
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: k3dAR 15. 12. 2021, 12:02:17
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 (https://cs.wikipedia.org/wiki/Roura_(Unix))
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: Bob Sinclair 15. 12. 2021, 12:08:32
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
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: Ignotus 15. 12. 2021, 14:59:19
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 {} \;
Název: Re:Jak získat rekurzivně všechny názvy souborů a adresářů z adresáře
Přispěvatel: jvb 16. 12. 2021, 16:51:30
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