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<span style="color: #0000ff;">.json</span>
/opt/td-agent/version-manifest<span style="color: #ff0000;">.txt</span>
[root@BS-PUB-CENT7-02 ~]# ls -1ad /opt/td-agent/* | xargs -I{} basename {} .txt
LICENSE
LICENSES
bin
embedded
etc
space test
usr
version-manifest<span style="color: #0000ff;">.json</span>
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
拡張子も除外する場合は、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を用いるとよいだろう。