awkプログラムのパスからファイル名を抽出する


21

awkスクリプトがあり、CSVファイルを渡しました。

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

私がやっていることはFILENAMEを取得することscript.awkです。FILENAMEは私に完全なパスを提供します。私はawkにいるので使用できませんbasename FILENAME

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

私はこれで試しました script.awk

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

しかし、私はこれを実行できませんscript.awkasgd.csvawkプログラム内で取得するにはどうすればよいですか?

回答:


33

いくつかのオプション:

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

または:

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

のこれらの実装はbasename一般的なケースで動作するはずですが、通常のファイルの場合は発生しませんが、代わりに空の文字列を返すかbasename /path/to/x///、空の文字列を返すようなコーナーケースでは動作しないことに注意してください。x//

ファイルパス(最後まで/)に現在のロケールで有効な文字を形成しないバイトシーケンスが含まれている場合、最初のものは適切に動作しません(通常、この種のことは8でエンコードされたファイル名を持つUTF-8ロケールで発生しますビットシングルバイト文字セット)。この問題を回避するには、ロケールをCに修正して、バイトのすべてのシーケンスが有効な文字を形成するようにします。


5
関数を導入せずに既存のawkスクリプト内で簡単に動作するコードが必要な場合は、次を使用する必要がありますn = split(FILENAME, a, "/"); basename=a[n];sub実際にはFILENAME変数を変更するため、使用しないでください(awkは値による呼び出しを使用するため、関数では問題になりません)。
シリ

10

このawkワンライナーをお試しください、

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

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

0

入力CSVから、または入力ファイルパスから直接エクスポートする最良の方法は、それを逆にして、1列を取得してから再び逆にすることができます。

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

または単に

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

0

Awkの分割機能を使用する

これを行う1つの方法は、split関数を使用することです。例えば:

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

これは複数のファイルでも機能します。例えば:

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

0

basenameコマンドが使用可能なシステムでは、awksystem()関数またはexpression | getline var構造を使用して外部basenameコマンドを呼び出すことができます。これは、Stephaneの回答に記載されているコーナーケースのアカウンティングに役立ちます

$ awk '{cmd=sprintf("basename %s",FILENAME);cmd | getline out; print FILENAME,out; exit}' /etc///passwd
/etc///passwd passwd
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.