Het gebruik van de uitvoer van ls
om bestandsnamen te krijgen is een slecht idee ](http://mywiki.wooledge.org/ParsingLs). Het kan leiden tot slecht functionerende en zelfs gevaarlijke scripts. Dit komt omdat een bestandsnaam elk karakter kan bevatten behalve /
en het null
-karakter, en ls
gebruikt geen van beide karakters als scheidingstekens, dus als een bestandsnaam een spatie of een nieuwe regel heeft, krijg je zal onverwachte resultaten.
Er zijn twee zeer goede manieren om te itereren over bestanden. Hier heb ik eenvoudigweg echo
gebruikt om te demonstreren dat je iets met de bestandsnaam doet; je kunt echter alles gebruiken.
De eerste is het gebruik van de native globbing functies van de shell.
for dir in */; do
echo "$dir"
done
De shell breidt */
uit tot afzonderlijke argumenten die de for
-lus leest; zelfs als er een spatie, newline, of een ander vreemd karakter in de bestandsnaam staat, zal for
elke volledige naam als een atomaire eenheid zien; het parseert de lijst op geen enkele manier.
Als je recursief in subdirectories wilt gaan, dan kan dit niet, tenzij je shell een aantal uitgebreide globbing-functies heeft (zoals bash
‘s globstar
. Als je shell deze functies niet heeft, of als je er zeker van wilt zijn dat je script op verschillende systemen werkt, dan is de volgende optie het gebruik van find
.
find . -type d -exec echo '{}' \;
Hier zal het find
commando echo
aanroepen en een argument van de bestandsnaam doorgeven. Het doet dit één keer voor elk bestand dat het vindt. Net als in het vorige voorbeeld is er geen ontleding van een lijst met bestandsnamen; in plaats daarvan wordt een bestandsnaam volledig als argument verzonden.
De syntaxis van het -exec
-argument ziet er een beetje grappig uit. find
neemt het eerste argument na -exec
en behandelt dat als het programma om te draaien, en elk volgend argument, neemt het als argument om door te geven aan dat programma. Er zijn twee speciale argumenten die -exec
moet zien. Het eerste is {}
; dit argument wordt vervangen door een bestandsnaam die de vorige delen van find
genereren. De tweede is ;
, die find
laat weten dat dit het einde is van de lijst met argumenten die aan het programma moeten worden doorgegeven; find
heeft dit nodig omdat je verder kunt gaan met meer argumenten die bedoeld zijn voor find
en niet voor het exec’d programma. De reden voor de Het gebruik van de uitvoer van
lsom bestandsnamen te krijgen is een slecht idee ]&003. Het kan leiden tot slecht functionerende en zelfs gevaarlijke scripts. Dit komt omdat een bestandsnaam elk karakter kan bevatten behalve
/en het
null-karakter, en
ls` gebruikt geen van beide karakters als scheidingstekens, dus als een bestandsnaam een spatie of een nieuwe regel heeft, krijg je zal onverwachte resultaten.
Er zijn twee zeer goede manieren om te itereren over bestanden. Hier heb ik eenvoudigweg echo
gebruikt om te demonstreren dat je iets met de bestandsnaam doet; je kunt echter alles gebruiken.
De eerste is het gebruik van de native globbing functies van de shell.
for dir in */; do
echo "$dir"
done
De shell breidt */
uit tot afzonderlijke argumenten die de for
-lus leest; zelfs als er een spatie, newline, of een ander vreemd karakter in de bestandsnaam staat, zal for
elke volledige naam als een atomaire eenheid zien; het parseert de lijst op geen enkele manier.
Als je recursief in subdirectories wilt gaan, dan kan dit niet, tenzij je shell een aantal uitgebreide globbing-functies heeft (zoals bash
’s globstar
. Als je shell deze functies niet heeft, of als je er zeker van wilt zijn dat je script op verschillende systemen werkt, dan is de volgende optie het gebruik van find
.
find . -type d -exec echo '{}' \;
Hier zal het find
commando echo
aanroepen en een argument van de bestandsnaam doorgeven. Het doet dit één keer voor elk bestand dat het vindt. Net als in het vorige voorbeeld is er geen ontleding van een lijst met bestandsnamen; in plaats daarvan wordt een bestandsnaam volledig als argument verzonden.
De syntaxis van het -exec
-argument ziet er een beetje grappig uit. find
neemt het eerste argument na -exec
en behandelt dat als het programma om te draaien, en elk volgend argument, neemt het als argument om door te geven aan dat programma. Er zijn twee speciale argumenten die -exec
moet zien. Het eerste is {}
; dit argument wordt vervangen door een bestandsnaam die de vorige delen van find
genereren. De tweede is ;
, die find
laat weten dat dit het einde is van de lijst met argumenten die aan het programma moeten worden doorgegeven; find
heeft dit nodig omdat je verder kunt gaan met meer argumenten die bedoeld zijn voor find
en niet voor het exec’d programma. De reden voor de is dat de shell ;
ook speciaal behandelt - het vertegenwoordigt het einde van een commando, dus we moeten er aan ontsnappen zodat de shell het als argument aan find
geeft in plaats van het voor zichzelf te consumeren; een andere manier om de shell zover te krijgen dat hij het niet speciaal behandelt is om het tussen aanhalingstekens te zetten: ';'
werkt net zo goed als \;
voor dit doel.