awk substrを使用して最後のフィールドを取得する


99

awkファイルへの絶対パスを指定して、ファイルの名前を取得するために使用しようとしています。
たとえば、/home/parent/child/filename取得したい入力パスが与えられたとき、filename 私は試しました:

awk -F "/" '{print $5}' input

完璧に動作します。
ただし、$5入力が次の構造の場合は正しくないハードコーディングです。

/home/parent/child1/child2/filename

したがって、一般的な解決策では、常に最後のフィールド(ファイル名になります)を取る必要があります。

awk substr関数でこれを行う簡単な方法はありますか?


2
誰かがこれを使用するのbasenameが公式の方法であることを指摘したので、これを使用awkすることはそれを軽く置くのは良くありません。:D
カシャップ

回答:


206

awk定義可能なフィールドセパレータに基づいてフィールドの行を分割するという事実を使用します。したがって、フィールドセパレーターを定義すると、次のようになり/ます。

awk -F "/" '{print $NF}' input

NF印刷、カレントレコードのフィールドの数を指す$NF最後の印刷手段。

したがって、次のようなファイルが与えられます。

/home/parent/child1/child2/child3/filename
/home/parent/child1/child2/filename
/home/parent/child1/filename

これは出力になります:

$ awk -F"/" '{print $NF}' file
filename
filename
filename

3
それは完全に動作します。$ NF変数については考えませんでした。あなたの即時のシンプルで効果的な答えをありがとう。
マリ

6
ペナルティについては、を使用してください$(NF-1)
イタチ

1
いくつかのDockerコマンドを操作するスクリプトを書いていて、これでうまくいきました。ありがとう!
ハーリン

30

この場合はbasenameawk次の代わりに使用することをお勧めします。

 $ basename /home/parent/child1/child2/filename
 filename

4
@Mari FYI dirnameは反対を行い、パスではなくファイルを削除します。
Chris Seymour


5

Perlソリューションを利用している場合、fedorquiのawkソリューションに似たものを以下に示します。

perl -F/ -lane 'print $F[-1]' input

-F//フィールド区切り
$F[-1]@F自動分割配列の最後の要素であることを指定します


1
ありがとう。これにより、最後の1つのフィールドを取得することができました。perl -F "/" -lane 'print $ F [-2]' input
riderchap

これは、パイプ入力から受け取るときにうまくいきました。perlについて完全に忘れていました。
クリストファー

3

それはベースネームの答えへのコメントであるべきですが、私は十分なポイントを持っていません。

二重引用符を使用しない場合、basenameスペース文字があるパスでは機能しません。

$ basename /home/foo/bar foo/bar.png
bar

引用符「」でOK

$ basename "/home/foo/bar foo/bar.png"
bar.png

ファイルの例

$ cat a
/home/parent/child 1/child 2/child 3/filename1
/home/parent/child 1/child2/filename2
/home/parent/child1/filename3

$ while read b ; do basename "$b" ; done < a
filename1
filename2
filename3

3

私はこれで3年遅れていることを知っていますが、パラメータの拡張を検討する必要があります。組み込みで高速です。

入力がvarである場合は、たとえば$ var1としましょう${var1##*/}。下を見て

$ var1='/home/parent/child1/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/filename'
$ echo ${var1##*/}
filename
$ var1='/home/parent/child1/child2/child3/filename'
$ echo ${var1##*/}
filename

2

5年遅れのように、私は知っています、すべての提案のおかげで、私はこれを次の方法で行っていました:

$ echo /home/parent/child1/child2/filename | rev | cut -d '/' -f1 | rev
filename

より良いマナーがあることに気付いてうれしい


-1

次のものも使用できます。

    sed -n 's/.*\/\([^\/]\{1,\}\)$/\1/p'

または

    sed -n 's/.*\/\([^\/]*\)$/\1/p'

1
この時点ではだれもこの回答に賛成していません。おそらくそれが比較的曖昧だからです:)
Josip Rodin
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.