Durchlaufen Sie Dateien ohne Verzeichnisse

11

Ich benötige mein Skript, um mit jeder Datei im aktuellen Verzeichnis etwas zu tun, mit Ausnahme von Unterverzeichnissen.

Im aktuellen Pfad befinden sich beispielsweise 5 Dateien, von denen eine ein Ordner (ein Unterverzeichnis) ist. Mein Skript sollte einen Befehl aktivieren, der beim Ausführen des Skripts als Argumente angegeben wird. Das heißt, "bash script wc -w" sollte die Wortanzahl jeder Datei im aktuellen Verzeichnis angeben, jedoch keinen der Ordner, damit die Ausgabe niemals eine der Zeilen "/ sub / dir: Is a directory" enthält.

Mein aktuelles Skript:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

Ich muss nur Verzeichnisse für die Schleife ausschließen, aber ich weiß nicht wie.

Tõnis Piip
quelle

Antworten:

11
#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Beachten Sie, dass auch Dateien vom Typ Symlink ausgeschlossen werden und der Symlink in eine Datei vom Typ Verzeichnis aufgelöst wird (was wahrscheinlich das ist, was Sie wollen).

Alternative (aus Kommentaren), nur nach Dateien suchen:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done
Laktak
quelle
@roaima gute Idee!
Laktak
2
Besser zu benutzen if [ -f "$file" ]; then .... Kein Verzeichnis würde nicht nur reguläre Dateien, sondern auch Sockets und Symlinks zurückgeben.
JRFerguson
@JRFerguson basierend auf der Frage des OP würde ich sagen, dass das Einschließen von Muffen und Rohren eine wirklich schlechte Idee wäre. Symlinks sind implizit ! -dbereits enthalten.
Roaima
Ich habe [-f $ file] in meinem endgültigen Skript verwendet. Beachten Sie das Fehlen von Anführungszeichen in der if-Bedingung. Fast überall, wo ich hinschaute, standen Anführungszeichen um $ file, aber ich musste sie löschen, damit mein Skript funktionierte.
Tõnis Piip
3

Hier ist eine Alternative zur Verwendung einer for-Schleife, wenn dies einfach ist (und keine Variablen in der Haupt-Shell & c festgelegt werden müssen).

Sie können findmit -execund verwenden -maxdepth 1, um ein erneutes Rekursieren in das Unterverzeichnis zu vermeiden.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

Dies [ -n "$1" ]dient dazu, die Ausführung aller Dateien im Verzeichnis zu vermeiden, wenn dem Skript keine Argumente übergeben werden.

Gregory Nisbet
quelle
2

In zsh können Sie Glob-Qualifizierer verwenden , um Platzhalterübereinstimmungen nach Dateityp einzuschränken. Wenn Sie (.)das Muster beispielsweise hinzufügen , wird es auf reguläre Dateien beschränkt.

wc -w *(.)

Um mit Dateinamen umzugehen, die mit -oder beginnen ., verwenden Sie wc -c -- *(.N)oder wc -c ./*(.N). Wenn Sie auch symbolische Links zu regulären Dateien einfügen möchten, machen Sie das *(-.).

Die anderen gängigen Shells verfügen nicht über eine solche Funktion. Sie müssen daher einen anderen Mechanismus zum Filtern nach Dateien verwenden, z. B. das Testen von Dateitypen in einer Schleife oder find.

Gilles 'SO - hör auf böse zu sein'
quelle
0

Bash für Schleife ohne Unterverzeichnisse ('/') und Links (@):

for f in `ls|egrep -v '/|@'`; do echo $f; done
James Armstrong
quelle