Ekstrak nama file dari path di program awk

21

Saya memiliki skrip awk dan saya telah mengirimkan file CSV ke sana.

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

Apa yang saya lakukan adalah memasukkan FILENAME ke dalam script.awk. FILENAME memberi saya seluruh jalur. Karena saya awk, saya tidak bisa menggunakan basename FILENAME.

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

Saya sudah mencoba dengan ini di dalam script.awk

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

tapi saya tidak bisa menjalankan ini di dalam script.awk. Bagaimana saya bisa masuk asgd.csvdalam program awk?

Aashu
sumber

Jawaban:

33

Beberapa pilihan:

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

Atau:

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

Perhatikan bahwa implementasi dari itu basenameharus berfungsi untuk kasus-kasus umum, tetapi tidak dalam kasus sudut seperti di basename /path/to/x///mana mereka mengembalikan string kosong alih-alih xatau di /mana mereka mengembalikan string kosong alih-alih /, meskipun untuk file biasa, itu tidak boleh terjadi.

Yang pertama tidak akan berfungsi dengan baik jika path file (hingga yang terakhir /) berisi urutan byte yang tidak membentuk karakter yang valid di lokal saat ini (biasanya hal semacam ini terjadi di lokal UTF-8 dengan nama file yang dikodekan dalam beberapa 8). set karakter byte tunggal). Anda dapat mengatasinya dengan memperbaiki lokal ke C di mana setiap urutan karakter byte bentuk yang valid.

Stéphane Chazelas
sumber
5
Jika Anda memerlukan kode yang akan bekerja dengan mudah dalam skrip awk ada tanpa memperkenalkan fungsi, Anda harus menggunakan: n = split(FILENAME, a, "/"); basename=a[n];. Jangan gunakan subkarena itu akan benar-benar mengubah FILENAMEvariabel (yang merupakan masalah dengan fungsi karena awk menggunakan panggilan berdasarkan nilai).
shiri
10

Coba satu baris ini,

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

cara terbaik untuk mengekspornya dari input CSV atau langsung dari jalur file input Anda dapat membalikkannya, kemudian mendapatkan 1 kolom dan kemudian balikkan lagi.

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

atau sederhana

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

Gunakan Fungsi Split Awk

Salah satu cara untuk melakukan ini adalah dengan menggunakan fungsi split. Sebagai contoh:

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

Ini bahkan berfungsi pada banyak file. Sebagai contoh:

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

Pada sistem di mana basenameperintah yang tersedia, salah satu bisa menggunakan awk's system()fungsi atau expression | getline varstruktur untuk memanggil eksternal basenameperintah. Ini dapat membantu menghitung kasus sudut yang disebutkan dalam jawaban Stephane .

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