Awk programında yoldan dosya adını ayıkla


21

Bir awk betiğim var ve ona bir CSV dosyası geçtim.

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

Ne yapıyorum FILENAME adlı kişiyi içeri almak script.awk. FILENAME bana tüm yolu veriyor. Ben awk içinde olduğum gibi kullanamıyorum basename FILENAME.

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

İçinde bunu denedim script.awk

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

ama bunu içeride yapamam script.awk. asgd.csvBir awk programına nasıl girebilirim ?

Yanıtlar:


33

Birkaç seçenek:

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

Veya:

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

Bu uygulamaların basenameyaygın durumlar için çalışması gerektiğini, ancak normal dosyalar için olmasa da , boş dizeyi nereye döndürdükleri veya basename /path/to/x///boş dizeyi döndürdükleri gibi köşe durumlarda işe yaramayacağını unutmayın .x//

Dosya yolları (en sonuncusu kadar /) geçerli yerel ayarda geçerli karakterler oluşturmayan bayt dizileri içeriyorsa birincisi düzgün çalışmaz (genellikle bu tür şeyler, bazı 8'de kodlanmış dosya adlarına sahip UTF-8 yerel ayarlarında gerçekleşir bit tek baytlık karakter kümesi). Her bayt dizisinin geçerli karakterler oluşturduğu yerel ayarı C'ye sabitleyerek bu sorunu çözebilirsiniz.


5
Eğer bir işlev katılarak olmadan varolan awk komut dosyası içinde kolayca çalışacak kodu gerekiyorsa, kullanmalısınız: n = split(FILENAME, a, "/"); basename=a[n];. Bu subaslında FILENAMEdeğişkeni (awk değerine göre çağrıyı kullandığından işlevle ilgili bir sorun değildir) değiştireceği için kullanmayın.
shiri

10

Bu garip tek astarı deneyin,

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

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

0

CSV girişinden veya doğrudan giriş dosyası yolundan dışa aktarmanın en iyi yolu, tersine çevirebilir, ardından 1 sütun alabilir ve tekrar tersine çevirebilirsiniz.

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

ya da sadece

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

0

Awk'un Bölme İşlevini Kullan

Bunu yapmanın bir yolu split işlevini kullanmaktır. Örneğin:

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

Bu, birden fazla dosyada bile çalışır. Örneğin:

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

0

Sistemlerde basenamekomut kullanılabilir, tek kullanabilirsiniz awk'ın system()işlev veya expression | getline varharici aramaya yapısını basenamekomutu. Bu Stephane'ın cevabında belirtilen köşe davalarının hesaplanmasına yardımcı olabilir .

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.