Ja som nový skript (bash) na termináli, find
sa správa ako:
find . -name "Ado*"
./Adobe ReaderScreenSnapz001.jpg
./Adobe ReaderScreenSnapz002.jpg
Zdá sa, že môj shellový skript oddeľuje názov súboru podľa medzery po "Adobe".
kód:
#!/bin/sh
i=1
for base_name in `find . -name "Ado*"`
do
echo $base_name
:
i=$((i+1))
done
Vráti sa niečo ako:
./Adobe
ReaderScreenSnapz001.jpg
:
Čo je zlé kde?
odpovede:
3 pre odpoveď č. 1Väčšina doterajších odpovedí bola použitá find ... | while read ...
ktorý funguje, ale cyklica while beží v podsvete (pretože je to súčasť potrubia), a tak sa váš počet súborov ($ i) stratí, keď sa ukončí podsveľ.Ak používate bash (t.j. musieť byť #!/bin/bash
, nie #!/bin/sh
), môžete použiť jeho funkciu nahradzovania procesov, aby ste predišli tomuto problému:
i=1
while IFS= read -r -u3 -d "" base_name; do
echo "$base_name"
:
i=$((i+1))
done 3< <(find . -name "Ado*" -print0)
Pridal som tu aj ďalšie triky, aby som to urobil robustnejším: nastavil som IFS na nulu (len pre príkaz na čítanie), aby sa nezostrihol vedúci alebo koniec bielych priestorov zo súborov; Používam čítanie "s -r
tak to nebude robiť vtipné veci s backslash v názvy súborov, používam nájsť "s -print0
a čítaj "s -d ""
používať nulové bajty ako oddeľovač súborov, takže to nebude ani zmätený linefeeds v názvoch súborov, používam dvojité kotácie okolo $base_name
vo vnútri slučky, takže sa to nepodarí rozdeliť(nie je dôležité pre echo, ale bude to dôležité, ak sa skutočne pokúsite použiť názvy súborov ako názvy súborov) a napokon prechádza zoznam súborov cez fd # 3 namiesto # 0 (stdin) s 3<
a čítaj "s -u3
možnosť, takže v prípade, že čokoľvek vnútri slučky číta zo stdin, nebude to náhodou inhalovať hromadu súborov.
1 pre odpoveď č. 2
find . -name "Ado*"
./Adobe ReaderScreenSnapz001.jpg
./Adobe ReaderScreenSnapz002.jpg
Na find
výsledok obsahuje white-spaces
.
Tak takto for loop
Iterácia súboru nad 4
položky.
Môžete zmeniť skript:
i=1
find . -name "Ado*" | while read base_name
do
echo $base_name
:
i=$((i+1))
done
1 pre odpoveď č. 3
Váš shell nahradí for base_name in $(find . -name "Ado*")
podľa
for base_name in ./Adobe ReaderScreenSnapz001.jpg ./Adobe ReaderScreenSnapz002.jpg
Z tohto dôvodu for
vidí štyri slová:
- ./Adobe
- ReaderScreenSnapz001.jpg
- ./Adobe
- ReaderScreenSnapz002.jpg
Moja rada: nahradiť for base_name in
podľa while read base_name
#!/bin/sh
i=1
find . -name "Ado*" |
while read base_name
do
echo $base_name
:
i=$((i+1))
done
read
číta riadok po riadku a zastaví while
opakovanie na konci jeho vstupu (find
).
read
Obchody v každom riadku base_name
variabilné.
1 pre odpoveď č. 4
Nie je nič zlého v shell skript.
Keď zavoláte program medzi spätných úvodzoviek príkaz je vykonaný v kľukaté proces a výsledok je vrátený do hlavného programu lexed a analyzované.A ako reťazec výsledok je rozdelený do niekoľkých token.
Mali by ste použiť čítať builtin takého
#! /bin/sh
i=0
find . -name "Ado*" | while read result
do
echo $result
i=$((i+1))
done