Linuxでファイルパスからファイル名だけを取り出したいときは、basenameコマンドを使用します。
たとえば、/home/user/logs/app.logというパスから、最後のapp.logだけを取り出したい場面があります。
このようなときに便利なのがbasenameコマンドです。
basenameは、ファイルそのものを操作するコマンドではなく、指定したパス文字列から末尾の名前部分を取り出すコマンドです。シェルスクリプトでファイル名を変数に入れたいときや、ログ処理・バックアップ処理・一括変換処理などでよく使われます。
この記事では、Linux初心者でも理解できるように、basenameコマンドの基本構文、拡張子を取り除く方法、dirnameとの違い、複数ファイルの処理、シェルスクリプトでの実用例、よくある注意点まで実例付きで解説します。
- basenameコマンドとは
- basenameコマンドの基本構文
- パスからファイル名だけを取り出す方法
- 相対パスでも使用できる
- ディレクトリ名を取り出す方法
- 末尾にスラッシュがある場合
- 拡張子を取り除く方法
- 複数のファイル名をまとめて処理する方法
- 複数ファイルの拡張子をまとめて取り除く方法
- basenameコマンドの主なオプション
- dirnameコマンドとの違い
- ファイルが存在しなくても処理できる
- シェルスクリプトでbasenameを使う方法
- スペースを含むパスを処理する方法
- for文で複数ファイルを処理する方法
- findコマンドと組み合わせる方法
- バックアップファイル名を作る例
- 拡張子なしの名前を使って出力ファイルを作る例
- basenameコマンドでよくある注意点
- basenameコマンドでよくあるエラー
- basename・dirname・realpathの違い
- よくある質問
- まとめ
basenameコマンドとは
basenameは、指定したパスから最後のファイル名またはディレクトリ名だけを取り出すLinuxコマンドです。
たとえば、次のようなパスがあるとします。
/home/user/sample.txt
basenameを使うと、末尾のsample.txtだけを取得できます。
basename /home/user/sample.txt
実行結果です。
sample.txt
ファイルの存在確認をしているわけではなく、あくまで文字列としてパスを処理している点が重要です。
basenameコマンドの基本構文
basenameコマンドの基本構文は次のとおりです。
basename パス
また、末尾の拡張子や指定した文字列を取り除きたい場合は、次のように書きます。
basename パス 削除したい末尾文字列
GNU版のbasenameでは、オプションを使って複数ファイルを処理することもできます。
basename [オプション] パス...
パスからファイル名だけを取り出す方法
最も基本的な使い方は、パスからファイル名だけを取り出す方法です。
basename /home/user/document/report.txt
実行結果です。
report.txt
ディレクトリ部分の/home/user/document/が取り除かれ、末尾のファイル名だけが表示されます。
相対パスでも使用できる
basenameは絶対パスだけでなく、相対パスにも使用できます。
basename ./logs/app.log
実行結果です。
app.log
現在のディレクトリを基準にしたパスでも、末尾の名前部分だけを取り出せます。
ディレクトリ名を取り出す方法
basenameはファイル名だけでなく、パス末尾のディレクトリ名も取り出せます。
basename /home/user/project
実行結果です。
project
末尾がディレクトリであっても、basenameは最後の名前部分を表示します。
末尾にスラッシュがある場合
パスの末尾にスラッシュが付いていても、通常は末尾のディレクトリ名を取り出せます。
basename /home/user/project/
実行結果です。
project
このように、末尾のスラッシュは取り除かれたうえで処理されます。
拡張子を取り除く方法
basenameでは、第2引数に削除したい末尾文字列を指定できます。
たとえば、.txtを取り除きたい場合は次のように実行します。
basename /home/user/report.txt .txt
実行結果です。
report
ファイル名から.txtが取り除かれました。
指定した文字列と一致した場合だけ削除される
第2引数は、末尾と一致した場合だけ削除されます。
basename report.txt .log
実行結果です。
report.txt
末尾が.logではないため、何も削除されません。
複数のファイル名をまとめて処理する方法
GNU版のbasenameでは、-aオプションを使うと複数のパスをまとめて処理できます。
basename -a /home/user/a.txt /home/user/b.txt /tmp/c.log
実行結果です。
a.txt
b.txt
c.log
複数のファイルパスから、それぞれファイル名だけを取り出せます。
複数ファイルの拡張子をまとめて取り除く方法
-sオプションを使うと、指定した接尾辞を複数ファイルから取り除けます。
basename -a -s .txt /home/user/a.txt /home/user/b.txt
実行結果です。
a
b
.txtが取り除かれたファイル名だけが表示されます。
basenameコマンドの主なオプション
| オプション | 説明 |
|---|---|
-a |
複数のパスをまとめて処理する |
-s 接尾辞 |
指定した接尾辞を取り除く |
-z |
出力の区切りを改行ではなくNUL文字にする |
--help |
ヘルプを表示する |
--version |
バージョン情報を表示する |
dirnameコマンドとの違い
basenameとよく一緒に使われるのがdirnameコマンドです。
basenameはパスの末尾の名前部分を取り出し、dirnameはそれ以外のディレクトリ部分を取り出します。
| コマンド | 取り出す部分 | 例 |
|---|---|---|
basename |
ファイル名・末尾の名前 | report.txt |
dirname |
ディレクトリ部分 | /home/user/document |
次のパスで確認してみます。
/home/user/document/report.txt
basenameを実行します。
basename /home/user/document/report.txt
実行結果です。
report.txt
dirnameを実行します。
dirname /home/user/document/report.txt
実行結果です。
/home/user/document
ファイル名を取り出したいならbasename、ディレクトリ部分を取り出したいならdirnameを使用します。
ファイルが存在しなくても処理できる
basenameは、実際にファイルが存在するかどうかを確認しません。
basename /not/exist/path/sample.txt
実行結果です。
sample.txt
存在しないパスでも、文字列として末尾の名前部分を取り出します。
ファイルの存在確認をしたい場合は、testコマンドや[ -e ファイル名 ]などを使います。
if [ -e /not/exist/path/sample.txt ]; then
echo "存在します"
else
echo "存在しません"
fi
シェルスクリプトでbasenameを使う方法
basenameは、シェルスクリプトでよく使われます。
パスからファイル名だけを変数に入れる例です。
path="/var/log/app.log"
filename=$(basename "$path")
echo "$filename"
実行結果です。
app.log
変数を使う場合は、パスをダブルクォートで囲むのが基本です。
スペースを含むパスを処理する方法
ファイル名やディレクトリ名にスペースが含まれている場合は、必ずクォートします。
basename "/home/user/My Documents/report.txt"
実行結果です。
report.txt
変数に入っている場合も同様です。
path="/home/user/My Documents/report.txt"
basename "$path"
クォートを忘れると、スペースで別々の引数として扱われ、意図しない結果になることがあります。
for文で複数ファイルを処理する方法
複数ファイルを順番に処理する場合は、for文と組み合わせられます。
for path in /var/log/*.log; do
filename=$(basename "$path")
echo "$filename"
done
実行結果の例です。
app.log
system.log
error.log
ログファイルの一覧から、ファイル名だけを取り出したい場合に便利です。
findコマンドと組み合わせる方法
findコマンドで見つけたファイルから、ファイル名だけを取り出すこともできます。
find /var/log -name "*.log" -type f
この結果をwhile文で処理します。
find /var/log -name "*.log" -type f | while read path; do
basename "$path"
done
ただし、ファイル名にスペースや特殊文字が含まれる可能性がある場合は、-print0とread -d ''を使う方法が安全です。
find /var/log -name "*.log" -type f -print0 | while IFS= read -r -d '' path; do
basename "$path"
done
バックアップファイル名を作る例
basenameを使うと、元のパスからファイル名だけを取り出してバックアップ名を作れます。
src="/etc/nginx/nginx.conf"
name=$(basename "$src")
cp "$src" "/tmp/${name}.bak"
この例では、/tmp/nginx.conf.bakというバックアップファイルを作成します。
拡張子なしの名前を使って出力ファイルを作る例
拡張子を取り除いた名前を使って、別の出力ファイル名を作ることもできます。
path="/home/user/report.txt"
name=$(basename "$path" .txt)
echo "$name"
実行結果です。
report
たとえば、変換後のファイル名を作るときに利用できます。
output="${name}.html"
echo "$output"
実行結果です。
report.html
basenameコマンドでよくある注意点
ファイルの存在確認はしない
basenameはパス文字列を処理するだけで、ファイルが存在するかは確認しません。
存在確認が必要な場合は、別途testコマンドを使います。
拡張子削除は末尾一致のみ
第2引数で指定した文字列は、ファイル名の末尾と一致した場合だけ削除されます。
basename archive.tar.gz .gz
実行結果です。
archive.tar
.tar.gzをまとめて取り除きたい場合は、次のように指定します。
basename archive.tar.gz .tar.gz
実行結果です。
archive
変数は必ずクォートする
シェルスクリプトで変数を使う場合は、次のようにダブルクォートで囲みます。
basename "$path"
クォートしないと、スペースや記号を含むパスで問題が起きる可能性があります。
basenameコマンドでよくあるエラー
missing operand
basename: missing operand
引数を指定せずに実行した場合に表示されます。
basename /home/user/sample.txt
extra operand
basename: extra operand 'file2.txt'
-aを付けずに複数のパスを渡した場合などに表示されることがあります。
複数のパスを処理する場合は、次のように-aを使用します。
basename -a file1.txt file2.txt
意図しない結果になる
スペースを含むパスをクォートしていない場合、意図しない結果になることがあります。
path="/home/user/My Documents/report.txt"
basename $path
安全に処理するには次のようにします。
basename "$path"
basename・dirname・realpathの違い
パス操作でよく使うコマンドには、basename、dirname、realpathがあります。
| コマンド | 役割 | 例 |
|---|---|---|
basename |
パス末尾の名前を取り出す | sample.txt |
dirname |
ディレクトリ部分を取り出す | /home/user |
realpath |
絶対パスへ変換する | /home/user/sample.txt |
単にファイル名だけほしい場合はbasename、ディレクトリ部分がほしい場合はdirname、相対パスを絶対パスにしたい場合はrealpathを使います。
よくある質問
basenameコマンドは何に使いますか?
パスからファイル名や末尾のディレクトリ名だけを取り出すために使います。シェルスクリプトでファイル名を変数に入れたい場合によく使われます。
basenameはファイルが存在しなくても使えますか?
はい。basenameはパス文字列を処理するコマンドなので、指定したファイルが存在しなくても結果を表示できます。
拡張子を取り除くにはどうすればよいですか?
第2引数に取り除きたい拡張子を指定します。
basename sample.txt .txt
複数のファイルをまとめて処理できますか?
GNU版のbasenameでは-aオプションを使うことで複数のパスをまとめて処理できます。
basename -a file1.txt file2.txt
basenameとdirnameの違いは何ですか?
basenameはパスの末尾のファイル名やディレクトリ名を取り出します。dirnameは、それ以外のディレクトリ部分を取り出します。
スペースを含むパスではどうすればよいですか?
パスや変数をダブルクォートで囲みます。
basename "$path"
Windowsのパスにも使えますか?
Linuxのbasenameは基本的にスラッシュ/区切りのパスを扱います。Windows形式のバックスラッシュ区切りパスでは、期待通りにならない場合があります。
UbuntuやCentOS Streamでも使えますか?
はい。Ubuntu、Debian、CentOS Stream、Rocky Linux、AlmaLinuxなど、一般的なLinuxディストリビューションで利用できます。
まとめ
basenameコマンドは、Linuxでパスからファイル名や末尾のディレクトリ名だけを取り出すためのコマンドです。
基本的な使い方は次のとおりです。
basename /home/user/sample.txt
実行結果です。
sample.txt
拡張子を取り除く場合は、第2引数に削除したい文字列を指定します。
basename /home/user/sample.txt .txt
実行結果です。
sample
複数ファイルをまとめて処理する場合は-a、接尾辞をまとめて削除する場合は-sを使います。
basename -a -s .txt /tmp/a.txt /tmp/b.txt
basenameはファイルを直接操作するコマンドではなく、パス文字列から必要な部分を取り出すコマンドです。
シェルスクリプトでファイル名を扱う場面では頻繁に使うため、dirnameやrealpathとあわせて覚えておくと、Linuxでのパス操作がかなり楽になります。




コメント