it-swarm.com.de

Extrahieren Sie den Dateinamen aus dem Pfad im awk-Programm

Ich habe ein awk-Skript und habe ihm eine CSV-Datei übergeben.

awk -f script.awk /home/abc/imp/asgd.csv

Was ich tue, ist, FILENAME innerhalb von script.awk Zu erhalten. FILENAME gibt mir den ganzen Weg. Da ich in awk bin, kann ich basename FILENAME Nicht verwenden.

print FILENAME;
/home/abc/imp/asgd.csv

Ich habe es innerhalb von script.awk Versucht.

echo $FILENAME | awk -F"/" '{print $NF}'

aber ich kann dies nicht innerhalb von script.awk ausführen. Wie kann ich asgd.csv Innerhalb eines awk-Programms erhalten?

22
Aashu

Mehrere Möglichkeiten:

awk '
  function basename(file) {
    sub(".*/", "", file)
    return file
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

Oder:

awk '
  function basename(file, a, n) {
    n = split(file, a, "/")
    return a[n]
  }
  {print FILENAME, basename(FILENAME)}' /path/to/file

Beachten Sie, dass diese Implementierungen von basename für die allgemeinen Fälle funktionieren sollten, jedoch nicht in Eckfällen wie basename /path/to/x///, In denen sie die leere Zeichenfolge anstelle von x oder /, wo sie die leere Zeichenfolge anstelle von / zurückgeben, obwohl dies bei normalen Dateien nicht passieren sollte.

Der erste funktioniert nicht richtig, wenn die Dateipfade (bis zum letzten /) Folgen von Bytes enthalten, die im aktuellen Gebietsschema keine gültigen Zeichen bilden (normalerweise geschieht dies in UTF-8-Gebietsschemas mit Dateinamen, die in einem 8-Bit-Einzelbyte-Zeichensatz codiert sind). Sie können dies umgehen, indem Sie das Gebietsschema auf C festlegen, wobei jede Bytefolge gültige Zeichen bildet.

33

Versuchen Sie diesen awk Einzeiler,

$ awk 'END{ var=FILENAME; split (var,a,/\//); print a[5]}' /home/abc/imp/asgd.csv
asgd.csv
10
Avinash Raj

Auf den Systemen, auf denen der Befehl basename verfügbar ist, kann man die Funktion system() von awk oder die Struktur expression | getline var Verwenden, um den externen Befehl basename aufzurufen. Dies kann helfen, Eckfälle zu berücksichtigen, die in Stephanes Antwort erwähnt sind.

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
2

am besten exportieren Sie es aus der Eingabe-CSV oder direkt aus dem Pfad der Eingabedatei. Sie können es umkehren, dann 1 Spalte abrufen und dann erneut umkehren.

function getFileFromPath() {
    FileName=$1
    cat $FileName | while read Filename
    do
        echo $Filename| rev | awk -v FS='/' '{print $1}' | rev 
    done
}

oder einfach

echo $FileNamePath| rev | awk -v FS='/' '{print $1}' | rev 
0
FariZ

Verwenden Sie die Split-Funktion von Awk

Eine Möglichkeit, dies zu tun, besteht darin, die Split-Funktion zu verwenden. Zum Beispiel:

awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' /path/to/file

Dies funktioniert sogar bei mehreren Dateien. Zum Beispiel:

$ awk '{idx = split(FILENAME, parts, "/"); print parts[idx]; nextfile}' \
      /etc/passwd /etc/group
passwd
group
0
CodeGnome