web-dev-qa-db-ja.com

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

次のような簡単な要件があります。
絶対ディレクトリでファイル名を取得しています。
たとえば/home/parent/child/filename
私の要件は、これからファイル名をカットすることです。
私が試したのは:

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

完璧に機能します。
しかし、ここでは$5をハードコーディングしています。これは、入力が次のような構造の場合は異なる場合があります。

/home/parent/child1/child2/filename

したがって、ハードコーディングなしで動的である必要があります。ロジックは次のとおりです。
常にファイル名となる最後のフィールドを使用します(逆から確認する必要があります)。

誰でもawk substr関数または他の関数で私を助けることができますか?

79
Mari

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
170
fedorqui

この場合、basenameの代わりにawkを使用することをお勧めします。

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

Perlソリューションを公開している場合は、fedorquiのawkソリューションに似ています。

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

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

5
Chris Koknat

別のオプションは、bashパラメーター置換 を使用することです。

$ foo="/home/parent/child/filename"
$ echo ${foo##*/}
filename
$ foo="/home/parent/child/child2/filename"
$ echo ${foo##*/}
filename
5
devnull

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

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

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

引用符 ""で大丈夫

$ 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
Pierre-Damien

私はこれに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
3
Adriano_epifas

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

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

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

2
Nicko Glayre