sagen, dass ich die folgende Struktur von Dateien und Verzeichnisse haben:Wie überspringe ich ein Verzeichnis in awk?
$ tree
.
├── a
├── b
└── dir
└── c
1 directory, 3 files
Das heißt, zwei Dateien a
und b
zusammen mit einem Verzeichnis dir
, wo eine andere Datei c
steht.
Ich möchte alle Dateien mit awk
(GNU Awk 4.1.1
, genau) verarbeiten, so mache ich so etwas wie diese:
$ gawk '{print FILENAME; nextfile}' * */*
a
b
awk: cmd. line:1: warning: command line argument `dir' is a directory: skipped
dir/c
Alles ist in Ordnung, aber die *
erweitert auch in das Verzeichnis dir
und awk
versucht zu verarbeiten es.
Also frage ich mich: gibt es eine native Art awk
kann überprüfen, ob das angegebene Element eine Datei ist oder nicht, und wenn ja, überspringen Sie es? Das heißt, ohne dafür system()
zu verwenden.
Ich machte es Arbeit der externen system
in BEGINFILE Aufruf:
$ gawk 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, FNR}' * */*
a
a 10
a.wk
a.wk 3
b
b 10
dir
dir is a dir, skipping
dir/c
dir/c 10
Beachten Sie auch die Tatsache, dass if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}
Zähler intuitiv funktioniert: es 1 ist, wenn true zurückgeben sollte, aber es gibt den Exit-Code.
Ich las in A.5 Extensions in gawk Not in POSIX awk:
- Verzeichnisse auf der Kommandozeile eine Warnung erzeugen und übersprungenen sind (siehe Command-line directories)
Und dann die verknüpfte Seite sagt:
4.11 Verzeichnisse auf der Befehlszeile
Gemäß dem POSIX-Standard müssen Dateien, die in der awk-Befehlszeile benannt sind, Textdateien sein. Es ist ein fataler Fehler, wenn sie es nicht sind. Die meisten Versionen von awk behandeln ein Verzeichnis in der Befehlszeile als schwerwiegender Fehler.
Standardmäßig erzeugt gawk eine Warnung für ein Verzeichnis im Befehl Zeile, ignoriert es aber ansonsten. Dies macht es einfacher Shell Platzhalter mit Ihrem awk-Programm verwenden:
$ gawk -f whizprog.awk * Directories could kill this program
Wenn eine der --posix oder --traditional Optionen gegeben, so kehrt glotzt in ein Verzeichnis auf der Kommandozeile als eine Behandlung fataler Fehler.
Siehe Extension Sample Readdir, für eine Möglichkeit zur Behandlung von Verzeichnissen als verwendbar Daten aus einem awk-Programm.
Und in der Tat ist es der Fall: der gleiche Befehl wie zuvor mit --posix
fehlschlägt:
$ gawk --posix 'BEGINFILE{print FILENAME; if (system(" [ ! -d " FILENAME " ]")) {print FILENAME, "is a dir, skipping"; nextfile}} ENDFILE{print FILENAME, NR}' * */*
gawk: cmd. line:1: fatal: cannot open file `dir' for reading (Is a directory)
ich den 16.7.6 Reading Directories
Abschnitt geprüft, die oben verbunden ist, und sie sprechen über readdir
:
Die Erweiterung readdir fügt einen Eingabe-Parser für Verzeichnisse hinzu. Die Verwendung ist wie folgt:
@load „readdir“
Aber ich bin nicht sicher, weder, wie man es nennen, noch wie es von der Kommandozeile zu verwenden.
Niiiice! Also "getline" auf einem Verzeichnis nicht direkt fehlgeschlagen, aber kann behandelt werden. – fedorqui
rechts. Als ich deine Frage zum ersten Mal gelesen habe, dachte ich, du würdest versuchen, awk nach Dateien/Verzeichnissen zu suchen (sorry - kurze Aufmerksamkeitsspanne!), Aber beim erneuten Lesen sieht es so aus, als würdest du nur verhindern wollen, dass jemand das Skript mit Nicht-Datei aufruft Argumente - es ist nichts falsch daran, dies zu tun und darüber ist, wie Sie es tun. Ich habe meine Antwort aktualisiert, um ein bisschen mehr Unterstützung dafür zu sein! –
Ja, genau. Es dient lediglich dazu, Warnungen zu vermeiden oder sogar Codes zu beenden, da ein Verzeichnis in einer angeblich nur-Dateien-Liste expandiert wird. Sehr interessante Antwort, von der ich sehr viel gelernt habe, danke:) – fedorqui