Linuxでフルパスからファイル名のみ取り出す方法
Pocket

LinuxやUNIXで、コンソール上でフルパスからファイル名のみを抽出する場合、以下のような方法がある。

1.basenameコマンドを用いる

基本はこれ。
basenameという、ファイル名のみ(ディレクトリを指定したら最後)を求めるコマンドがあるので、これを利用する。
パイプで渡す場合はxargsを使う必要があるので注意。

basename PATH
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | xargs -n1 basename
LICENSE
LICENSES
bin
embedded
etc
usr
version-manifest.json
version-manifest.txt

 

なお、basenameコマンドの場合スペースを含んだPATHを渡す場合はエスケープなり、ダブルクォーテーションなりでくくってやる必要があるので注意。

[root@BS-PUB-CENT7-02 ~]# basename /opt/td-agent/space test
space
[root@BS-PUB-CENT7-02 ~]# basename /opt/td-agent/space\ test
space test
[root@BS-PUB-CENT7-02 ~]# basename "/opt/td-agent/space test"
space test

 

xargsで渡す場合は、-Iと組み合わせてやるといいだろう。

[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space*
/opt/td-agent/space test
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space* | xargs basename
space
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/space* | xargs -I{} basename "{}"
space test

 

一応、拡張子(.txtなど)を指定することで、その拡張子を排除して出力させることもできる…のだが、ベタ打ちなのであまり使い勝手はよくないかも。

[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | xargs -I{} basename {} .txt
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest.json
version-manifest

 

2.awkを用いる

awkでディレクトリ部分を除外する場合は、区切り文字を「/」にしてやり、$NF(最後の列)をprintしてやればよい。

awk -F/ '{print $NF}'
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | awk -F/ '{print $NF}'
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest.json
version-manifest.txt
Sponsored Links

拡張子も除外する場合は、awk内でgsubを使って置換してやるといいだろう。
記述例は以下。

awk -F/ '{gsub (/\.[^/.]*$/,"",$NF);print $NF}'
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*
/opt/td-agent/LICENSE
/opt/td-agent/LICENSES
/opt/td-agent/bin
/opt/td-agent/embedded
/opt/td-agent/etc
/opt/td-agent/space test
/opt/td-agent/usr
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | awk -F/ '{gsub (/\.[^/.]*$/,"",$NF);print $NF}'
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest
version-manifest

 

3.sedを用いる

awkと同様の処理を、sedを用いるパターン。
後方参照をすることで実現する。

sed -E 's/^(\/.*\/)*(.*)/\2/' 
sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2/' # 拡張子もけずるパターン
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.*
/opt/td-agent/version-manifest.json
/opt/td-agent/version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.* | sed -E 's/^(\/.*\/)*(.*)/\2/'
version-manifest.json
version-manifest.txt
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/*.* | sed -E 's/^([\/]?.*\/)*(.*)\..*$/\2/'
version-manifest
version-manifest

 

4.bashのパラメータ展開を用いる

一度変数に代入する必要はあるが、bashのパラメータ展開を用いる方法もある。

${VAR##*/}
[root@BS-PUB-CENT7-02 ~]# TEST_PATH=/opt/td-agent/version-manifest.json
[root@BS-PUB-CENT7-02 ~]# echo $TEST_PATH
/opt/td-agent/version-manifest.json
[root@BS-PUB-CENT7-02 ~]# echo ${TEST_PATH##*/}
version-manifest.json

 

拡張子の削除は同時に行えないので、awkやsedと組み合わせるとよいだろう。

 

番外編 ~出力元がfindの場合~

そもそも、変換元のPATHの出力をfindで行っているのであれば、「-printf」でファイル名だけを指定すればよい。

find ./ -printf "%f\n"

 

拡張子削除については、awkやsedを用いるとよいだろう。

 

 

Pocket

Written by blacknon

インフラ系のSE。一時期はプログラマ。 仮想化とオープンソースに興味あり。一日中寝てたい今日このごろ。 スペインとかで働きたいなぁ…(シエスタがあるので)

Leave a Comment

メールアドレスが公開されることはありません。

*