Ich versuche mit meiner Bash (neueste Ubuntu LTS-Version) alle Dateien mit einer bestimmten Erweiterung in einem Verzeichnis und seinen Unterverzeichnissen zu finden.
Folgendes steht in einer Skriptdatei:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
do
echo "dir :$directory"
echo "filename: $i"
# echo ${i#*.}
extension=`echo "$i" | cut -d'.' -f2`
echo "Erweiterung $extension"
if [ -f "$i" ]; then
if [ $extension == $suffix ]; then
echo "$i ends with $in"
else
echo "$i does NOT end with $in"
fi
elif [ -d "$i" ]; then
browsefolders "$i"
fi
done
}
browsefolders "$directory"
Wenn ich dieses Skript im Terminal starte, heißt es leider:
[: 29: in: unexpected operator
(mit $extension
statt 'in'
)
Was ist hier los, wo ist der Fehler? Aber diese geschweifte Klammer
Antworten:
ist etwas kürzer als das Ganze (und sicherer - behandelt Leerzeichen in Dateinamen und Verzeichnisnamen).
Ihr Skript schlägt wahrscheinlich fehl, wenn Einträge,
.
deren Name kein enthält ,$extension
leer sind.quelle
find
ist standardmäßig rekursiv. Sie können die Tiefen begrenzen, wenn Sie möchten (siehe Manpage).Beispiel: Um alle
csv
Dateien im aktuellen Verzeichnis und seinen Unterverzeichnissen zu finden, verwenden Sie:quelle
Die Syntax, die ich verwende, unterscheidet sich ein wenig von der von @Matt vorgeschlagenen:
(Es ist ein Tastendruck weniger).
quelle
Ohne zu verwenden
find
:quelle
grep
ist hier nicht wirklich notwendig.awk
hat reguläre Ausdrücke und könnte seine Ausgabe auf Werte beschränken, die einem Muster entsprechen.awk|grep
ist ein Anti-Muster. Lass awk das Greppen machen.{
fehlt ein nachbrowsefolders ()
$in
sollte sein$suffix
cut
bekommt nur den mittleren Teil vonfront.middle.extension
. Sie sollten Ihr Shell-Handbuch auf${varname%%pattern}
und Freunde lesen .Ich gehe davon aus, dass Sie dies als Übung in Shell-Skripten tun, ansonsten die
find
bereits vorgeschlagene Lösung der richtige Weg.Verwenden Sie, um die korrekte Shell-Syntax zu überprüfen, ohne ein Skript auszuführen
sh -n scriptname
.quelle
quelle
Obwohl die Verwendung von
find
Befehlen hier nützlich sein kann, bietet die Shell selbst Optionen, um diese Anforderung ohne Tools von Drittanbietern zu erfüllen. Dasbash
Shell bietet eine erweiterte Glob-Unterstützungsoption, mit der Sie die Dateinamen unter rekursiven Pfaden abrufen können, die mit den gewünschten Erweiterungen übereinstimmen.Die erweiterte Option
extglob
muss mit der folgendenshopt
Option festgelegt werden. Die Optionen werden mit der-s
Unterstützung aktiviert und mit dem-u
Flag deaktiviert . Darüber hinaus können Sie einige weitere Optionen verwenden, z. B.nullglob
bei denen ein nicht übereinstimmender Glob vollständig weggefegt und durch einen Satz von Nullwörtern ersetzt wird. Undglobstar
das ermöglicht es, alle Verzeichnisse zu durchsuchenJetzt müssen Sie nur noch den Glob-Ausdruck bilden, um die Dateien einer bestimmten Erweiterung einzuschließen. Dies können Sie wie folgt tun. Wir verwenden ein Array, um die Glob-Ergebnisse zu füllen, da die Dateinamen mit Sonderzeichen intakt bleiben und nicht durch Wortaufteilung durch die Shell beschädigt werden, wenn sie richtig zitiert und erweitert werden.
Zum Beispiel, um alle
*.csv
Dateien in den rekursiven Pfaden aufzulistenDie Option
**
besteht darin, die Unterordner zu durchsuchen, und*.csv
ist eine globale Erweiterung, um alle Dateien der genannten Erweiterungen einzuschließen . Jetzt zum Drucken der eigentlichen Dateien einfach tunDie Verwendung eines Arrays und eine ordnungsgemäße Erweiterung in Anführungszeichen ist der richtige Weg, wenn Sie in Shell-Skripten verwendet werden. Für die interaktive Verwendung können Sie jedoch einfach
ls
den glob-Ausdruck als verwendenDies könnte sehr gut erweitert werden, um mehrere Dateien abzugleichen, dh Dateien, die mit mehreren Erweiterungen enden (dh ähnlich dem Hinzufügen mehrerer Flags im
find
Befehl). Stellen Sie sich zum Beispiel vor , Sie müssten alle rekursiven Bilddateien abrufen, dh Erweiterungen*.gif
,*.png
und*.jpg
alles, was Sie brauchen, istDies könnte sehr gut erweitert werden, um auch negative Ergebnisse zu erzielen. Mit der gleichen Syntax könnte man die Ergebnisse des Glob verwenden, um Dateien eines bestimmten Typs auszuschließen. Angenommen, Sie möchten Dateinamen mit den oben genannten Erweiterungen ausschließen
Das Konstrukt
!()
ist eine Negationsoperation, bei der keine der darin aufgeführten Dateierweiterungen enthalten ist, und es|
handelt sich um einen Wechseloperator, wie er in der Bibliothek für erweiterte reguläre Ausdrücke verwendet wird, um eine ODER-Übereinstimmung der Globs durchzuführen.Beachten Sie, dass diese erweiterte Glob-Unterstützung in der POSIX-Bourne-Shell nicht verfügbar ist und nur für neuere Versionen von spezifisch ist
bash
. Wenn Sie also die Portabilität der Skripte in Betracht ziehen, die unter POSIX undbash
Shells ausgeführt werden, ist diese Option nicht richtig.quelle
Um alle
pom.xml
Dateien in Ihrem aktuellen Verzeichnis zu finden und auszudrucken, können Sie Folgendes verwenden:quelle
quelle
quelle