
Ich habe derzeit diesen Befehl, der jeden Dateinamen erfolgreich in einer eigenen Zeile ausgibt:
find . -exec echo {} \;
Ich versuche die Logik aufzuteilen, sodass der find
Befehl eine Funktion ausführt. Basierend aufdiese FrageIch habe Folgendes versucht:
my_function() {
echo $1
}
export -f my_function
find . -exec bash -c 'my_function "$@"' bash {} +
Dann bekomme ich diese Ausgabe:
.
Ich habe auch versucht, $@
durch zu ersetzen $*
, aber das führt dazu $1
, dass jede einzelne Datei ohne Zeilenumbrüche ist. Ich möchte eine Logik ausführen, die jede Datei überprüft, also möchte ich immer $1
nur eine Datei auf einmal. Ich habe versucht, die Ausgabe mit Leerzeichen durch aufzuteilen, for file in $1
aber das funktioniert nicht für Dateien, die Leerzeichen im Dateinamen haben. Wie führe ich eine Bash-Funktion für jede vom find
Befehl gefundene Datei aus?
BEARBEITEN: Hier ist das gesamte Skript, das ich verwende. Es scheint gut zu funktionieren.
# Ensures that non-csproj text files are formatted with LF line endings.
format() {
for pathname do
if [[ $pathname == *"git"* ]]; then
continue
elif [[ $pathname == *"csproj"* ]]; then
continue
fi
dos2unix $pathname
done
}
export -f format
find . -exec bash -c 'format "$@"' bash {} \;
Antwort1
Zum Ausführen dos2unix --newline
auf allen regulären Dateien im aktuellen Verzeichnis und darunter und Vermeiden aller Dateien, deren Name die Zeichenfolge enthält git
:
find . -type f ! -name '*git*' -exec dos2unix --newline {} +
Das heißt, alle regulären Dateien suchen, deren Namen nicht mit dem Muster übereinstimmen , und alle in möglichst großen Batches gleichzeitig *git*
ausführen . Ändern Sie es in , um alle Dateien zu vermeiden, deren Pfadname die Zeichenfolge enthält (z. B. Dateien in Verzeichnissen).dos2unix --newline
! -name '*git*'
! -path '*git*'
git
.git
Um explizit alle .git
Verzeichnisse zu vermeiden, aber alles andere einzuschließen, was git
im Namen enthalten sein könnte:
find . -name .git -prune -o -type f -exec dos2unix --newline {} +
Dadurch wird find
sogar das Betreten eines Verzeichnisses verhindert, .git
indem -prune
solche Pfade aus dem Suchbaum gelöscht werden.
Antwort vor der Bearbeitung der Frage:
Ihre Funktion gibt nur ihr erstes Argument aus. Der Punkt ist der Suchpfad der obersten Ebene, den Sie mit verwenden find
. Er wird übergeben, da Sie keine besondere Filterung der Verzeichniseinträge vornehmen (wie beispielsweise bei „ -type f
Nur für reguläre Dateien“, „oder -name
“ oder einem anderen Testtyp find
).
Wenn Sie möchten, dass Ihre Funktion alle Argumente ausgibt, verwenden Sie entweder
my_function() {
printf '%s\n' "$@"
}
wodurch printf
jedes Argument mit einer neuen Zeile dazwischen gedruckt wird, oder
my_function() {
for pathname do
printf '%s\n' "$pathname"
done
}
das die Argumente durchläuft und printf
für jedes einmal aufruft.
Dies würde ordnungsgemäß funktionieren, wenn Sie die Funktion wie folgt aufrufen würden:
my_function "$@"
aus Ihrem Inline- bash -c
Skript heraus. Es "$@"
wird auf alle dem Skript übergebenen Argumente erweitert, einzeln in Anführungszeichen gesetzt.
Eine andere Möglichkeit wäre, die Schleife in das bash -c
Skript zu verschieben:
for pathname do
my_function "$pathname"
done
und dann haben
my_function () {
printf '%s\n' "$1"
}
Damit würden Sie explizit das tun, was Sie tun möchten, d. h. die Funktion einmal für jeden Pfadnamen aufrufen.
Der find
Befehl würde dann entweder so aussehen:
find . -exec bash -c 'for pathname do my_function "$pathname"; done' bash {} +
oder, wohl etwas lesbarer,
find . -exec bash -c '
for pathname do
my_function "$pathname"
done' bash {} +
Dies wäre übrigens dasselbe wie
shopt -s globstar nullglob dotglob
for pathname in ./**/*; do
my_function "$pathname"
done
außer dass dies .
nicht verarbeitet würde. Wenn Sie dies verwenden, müssen Sie Ihre my_function
Funktion nicht exportieren.
Mit der Schleife innerhalb der Funktion (wie in den ersten beiden Codeteilen dieser Antwort) würde dies verkürzt werden auf
shopt -s globstar nullglob dotglob
my_function ./**/*