dirnameコマンドとは?Linuxでパスからディレクトリ部分を取り出す方法

Linux

Linuxでファイルパスからディレクトリ部分だけを取り出したいときは、dirnameコマンドを使用します。

たとえば、/home/user/logs/app.logというパスから、ファイル名のapp.logを除いた/home/user/logsだけを取り出したい場面があります。

このようなときに便利なのがdirnameコマンドです。

dirnameは、実際にディレクトリを作成したり移動したりするコマンドではありません。指定したパス文字列から、末尾のファイル名やディレクトリ名を除いた部分を表示するコマンドです。

シェルスクリプトでファイルの保存先ディレクトリを取得したいとき、バックアップ先を作りたいとき、ログファイルの親ディレクトリを確認したいときなどによく使われます。

この記事では、Linux初心者でも理解できるように、dirnameコマンドの基本構文、basenameとの違い、相対パス・絶対パスでの使い方、シェルスクリプトでの活用例、よくある注意点まで実例付きで解説します。

  1. dirnameコマンドとは
  2. dirnameコマンドの基本構文
  3. パスからディレクトリ部分を取り出す方法
  4. 相対パスでも使用できる
  5. ファイル名だけを指定した場合
  6. ルート直下のファイルを指定した場合
  7. 末尾にスラッシュがある場合
  8. basenameコマンドとの違い
  9. ファイルが存在しなくても処理できる
  10. 複数のパスをまとめて処理する方法
  11. dirnameコマンドの主なオプション
  12. -zオプションでNUL区切りにする方法
  13. シェルスクリプトでdirnameを使う方法
  14. スペースを含むパスを処理する方法
  15. 親ディレクトリを作成してからファイルを保存する例
  16. バックアップ先ディレクトリを取得する例
  17. スクリプト自身の場所を取得する例
  18. findコマンドと組み合わせる方法
  19. 重複したディレクトリをまとめる例
  20. dirname・basename・realpathの違い
  21. dirnameコマンドでよくある注意点
    1. 実際のディレクトリ存在確認はしない
    2. ファイル名だけを指定するとドットが返る
    3. 変数は必ずクォートする
  22. dirnameコマンドでよくあるエラー
    1. missing operand
    2. 意図したパスと違う結果になる
    3. スペースを含むパスで分割される
  23. よくある質問
    1. dirnameコマンドは何に使いますか?
    2. dirnameはファイルが存在しなくても使えますか?
    3. ファイル名だけを指定するとどうなりますか?
    4. basenameとの違いは何ですか?
    5. 複数のパスをまとめて処理できますか?
    6. スペースを含むパスではどうすればよいですか?
    7. dirnameで絶対パスに変換できますか?
    8. UbuntuやCentOS Streamでも使えますか?
  24. まとめ

dirnameコマンドとは

dirnameは、指定したパスからディレクトリ部分を取り出すLinuxコマンドです。

たとえば、次のようなパスがあるとします。

/home/user/document/report.txt

dirnameを使うと、末尾のreport.txtを除いたディレクトリ部分だけを取得できます。

dirname /home/user/document/report.txt

実行結果です。

/home/user/document

ファイル名を取り出すbasenameとは反対に、dirnameはディレクトリ部分を取り出すコマンドです。

dirnameコマンドの基本構文

dirnameコマンドの基本構文は次のとおりです。

dirname パス

複数のパスを指定することもできます。

dirname パス1 パス2 パス3

指定したパスごとに、ディレクトリ部分が表示されます。

パスからディレクトリ部分を取り出す方法

最も基本的な使い方は、ファイルパスからディレクトリ部分を取り出す方法です。

dirname /home/user/document/report.txt

実行結果です。

/home/user/document

末尾のreport.txtが取り除かれ、親ディレクトリのパスだけが表示されます。

相対パスでも使用できる

dirnameは、絶対パスだけでなく相対パスにも使用できます。

dirname ./logs/app.log

実行結果です。

./logs

現在のディレクトリを基準にしたパスでも、ファイル名を除いた部分を取得できます。

ファイル名だけを指定した場合

ディレクトリ部分を含まないファイル名だけを指定した場合、dirname.を返します。

dirname sample.txt

実行結果です。

.

.は現在のディレクトリを意味します。

つまり、sample.txtは現在のディレクトリにあるファイルとして扱われるため、ディレクトリ部分は.になります。

ルート直下のファイルを指定した場合

ルートディレクトリ直下のファイルを指定した場合は、/が返ります。

dirname /sample.txt

実行結果です。

/

これは、/sample.txtの親ディレクトリがルートディレクトリ/だからです。

末尾にスラッシュがある場合

末尾にスラッシュがあるパスを指定した場合、最後の要素を取り除いたディレクトリ部分が表示されます。

dirname /home/user/project/

実行結果です。

/home/user

/home/user/project/の末尾要素はprojectとして扱われるため、その親ディレクトリである/home/userが表示されます。

basenameコマンドとの違い

dirnameとよく一緒に使われるのがbasenameコマンドです。

この2つは、どちらもパス文字列を分解するためのコマンドですが、取り出す部分が異なります。

コマンド 取り出す部分
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を使用します。

ファイルが存在しなくても処理できる

dirnameは、実際にファイルやディレクトリが存在するかどうかを確認しません。

dirname /not/exist/path/sample.txt

実行結果です。

/not/exist/path

存在しないパスであっても、文字列として処理されます。

ファイルやディレクトリの存在確認をしたい場合は、testコマンドや[ -e パス ]を使います。

if [ -e /not/exist/path/sample.txt ]; then
  echo "存在します"
else
  echo "存在しません"
fi

複数のパスをまとめて処理する方法

dirnameは、複数のパスを一度に処理できます。

dirname /home/user/a.txt /var/log/app.log /tmp/test/file.dat

実行結果です。

/home/user
/var/log
/tmp/test

それぞれのパスから、ディレクトリ部分だけが表示されます。

dirnameコマンドの主なオプション

オプション 説明
-z 出力の区切りを改行ではなくNUL文字にする
--help ヘルプを表示する
--version バージョン情報を表示する

dirnameは比較的シンプルなコマンドなので、よく使うオプションは多くありません。

-zオプションでNUL区切りにする方法

-zオプションを使用すると、出力の区切りが改行ではなくNUL文字になります。

dirname -z /home/user/a.txt /home/user/b.txt

通常の画面表示では分かりにくいですが、ファイル名に改行などの特殊文字が含まれる可能性がある場合に、安全な処理へつなげやすくなります。

一般的な手作業ではあまり使いませんが、シェルスクリプトで堅牢に処理したい場合に使われます。

シェルスクリプトでdirnameを使う方法

dirnameは、シェルスクリプト内で親ディレクトリを取得したいときによく使います。

たとえば、ファイルパスからディレクトリ部分だけを変数へ入れる例です。

path="/var/log/app/app.log"
dir=$(dirname "$path")

echo "$dir"

実行結果です。

/var/log/app

変数を扱う場合は、パスをダブルクォートで囲むのが基本です。

スペースを含むパスを処理する方法

ファイル名やディレクトリ名にスペースが含まれている場合は、必ずクォートします。

dirname "/home/user/My Documents/report.txt"

実行結果です。

/home/user/My Documents

変数に入っている場合も同様です。

path="/home/user/My Documents/report.txt"
dirname "$path"

クォートを忘れると、スペースで別々の引数として扱われ、意図しない結果になる可能性があります。

親ディレクトリを作成してからファイルを保存する例

dirnameは、ファイル保存前に親ディレクトリを作成する処理でよく使われます。

output="/tmp/report/2026/result.txt"
dir=$(dirname "$output")

mkdir -p "$dir"
echo "結果を保存します" > "$output"

この例では、まず/tmp/report/2026を作成し、その後にresult.txtへ書き込みます。

シェルスクリプトで出力先ディレクトリが存在しない場合に便利です。

バックアップ先ディレクトリを取得する例

バックアップ処理でもdirnameは便利です。

src="/etc/nginx/nginx.conf"
dir=$(dirname "$src")

echo "$dir"

実行結果です。

/etc/nginx

元ファイルが存在するディレクトリを取得して、同じ場所にバックアップファイルを作ることもできます。

src="/etc/nginx/nginx.conf"
dir=$(dirname "$src")
base=$(basename "$src")

cp "$src" "$dir/${base}.bak"

この例では、/etc/nginx/nginx.conf.bakを作成します。

スクリプト自身の場所を取得する例

シェルスクリプトでは、自分自身が置かれているディレクトリを取得したいことがあります。

script_dir=$(dirname "$0")
echo "$script_dir"

ただし、$0は実行方法によって相対パスになることがあります。

絶対パスとして扱いたい場合は、cdpwdと組み合わせる方法が使われます。

script_dir=$(cd "$(dirname "$0")" && pwd)
echo "$script_dir"

より厳密なパス解決が必要な場合は、realpathコマンドの利用も検討します。

findコマンドと組み合わせる方法

findコマンドで見つけたファイルから、親ディレクトリだけを取り出すこともできます。

find /var/log -name "*.log" -type f

この結果をwhile文で処理します。

find /var/log -name "*.log" -type f | while read path; do
  dirname "$path"
done

ファイル名にスペースや特殊文字が含まれる可能性がある場合は、-print0read -d ''を使う方法が安全です。

find /var/log -name "*.log" -type f -print0 | while IFS= read -r -d '' path; do
  dirname "$path"
done

重複したディレクトリをまとめる例

複数ファイルの親ディレクトリを取得すると、同じディレクトリが重複して表示されることがあります。

find /var/log -name "*.log" -type f | while read path; do
  dirname "$path"
done | sort | uniq

sortuniqを組み合わせると、重複を取り除いて一覧化できます。

dirname・basename・realpathの違い

パス操作でよく使うコマンドには、dirnamebasenamerealpathがあります。

コマンド 役割
dirname パスのディレクトリ部分を取り出す /home/user/document
basename パス末尾のファイル名を取り出す report.txt
realpath 相対パスを絶対パスへ変換する /home/user/document/report.txt

親ディレクトリを取り出したい場合はdirname、ファイル名だけを取り出したい場合はbasename、正規化された絶対パスが欲しい場合はrealpathを使います。

dirnameコマンドでよくある注意点

実際のディレクトリ存在確認はしない

dirnameは、パス文字列を処理するだけです。

存在しないパスを指定しても、文字列としてディレクトリ部分を表示します。

dirname /not/exist/sample.txt

実行結果です。

/not/exist

実際に存在するか確認したい場合は、次のようにします。

dir=$(dirname "/not/exist/sample.txt")

if [ -d "$dir" ]; then
  echo "ディレクトリは存在します"
else
  echo "ディレクトリは存在しません"
fi

ファイル名だけを指定するとドットが返る

ファイル名だけを指定した場合は、現在のディレクトリを意味する.が返ります。

dirname sample.txt

実行結果です。

.

エラーではなく、正常な動作です。

変数は必ずクォートする

シェルスクリプトで変数を使う場合は、次のようにダブルクォートで囲みます。

dirname "$path"

スペースや記号を含むパスで問題が起きるのを防げます。

dirnameコマンドでよくあるエラー

missing operand

dirname: missing operand

引数を指定せずに実行した場合に表示されます。

対象のパスを指定して実行してください。

dirname /home/user/sample.txt

意図したパスと違う結果になる

末尾にスラッシュがある場合や、相対パスを指定している場合、想定と異なるように見える結果になることがあります。

dirname ./sample.txt

実行結果です。

.

./sample.txtは現在のディレクトリにあるファイルを意味するため、ディレクトリ部分は.になります。

スペースを含むパスで分割される

変数をクォートしていない場合、スペースでパスが分割されます。

path="/home/user/My Documents/report.txt"
dirname $path

安全に処理するには、必ず次のように書きます。

dirname "$path"

よくある質問

dirnameコマンドは何に使いますか?

ファイルパスからディレクトリ部分だけを取り出すために使います。シェルスクリプトで親ディレクトリを取得したいときによく利用されます。

dirnameはファイルが存在しなくても使えますか?

はい。dirnameはパス文字列を処理するコマンドなので、指定したファイルやディレクトリが存在しなくても結果を表示できます。

ファイル名だけを指定するとどうなりますか?

現在のディレクトリを意味する.が表示されます。

dirname sample.txt

basenameとの違いは何ですか?

basenameはパス末尾のファイル名やディレクトリ名を取り出します。dirnameは、その末尾を除いたディレクトリ部分を取り出します。

複数のパスをまとめて処理できますか?

はい。複数のパスを指定すると、それぞれのディレクトリ部分が表示されます。

dirname /tmp/a.txt /var/log/app.log

スペースを含むパスではどうすればよいですか?

パスや変数をダブルクォートで囲みます。

dirname "$path"

dirnameで絶対パスに変換できますか?

いいえ。dirnameは指定されたパス文字列からディレクトリ部分を取り出すだけです。絶対パスへ変換したい場合はrealpathを使用します。

UbuntuやCentOS Streamでも使えますか?

はい。Ubuntu、Debian、CentOS Stream、Rocky Linux、AlmaLinuxなど、一般的なLinuxディストリビューションで利用できます。

まとめ

dirnameコマンドは、Linuxでパスからディレクトリ部分だけを取り出すためのコマンドです。

基本的な使い方は次のとおりです。

dirname /home/user/sample.txt

実行結果です。

/home/user

ファイル名だけを指定した場合は、現在のディレクトリを意味する.が表示されます。

dirname sample.txt

実行結果です。

.

basenameはファイル名部分を取り出し、dirnameはディレクトリ部分を取り出します。

basename /home/user/sample.txt
dirname /home/user/sample.txt

シェルスクリプトでは、親ディレクトリを作成してからファイルへ書き込む処理や、バックアップファイルを作成する処理でよく使われます。

output="/tmp/report/result.txt"
dir=$(dirname "$output")

mkdir -p "$dir"
echo "保存します" > "$output"

dirnameはファイルやディレクトリを直接操作するのではなく、パス文字列を処理するコマンドです。

basenamerealpathとあわせて覚えておくと、Linuxでのパス操作やシェルスクリプト作成がかなり楽になります。

コメント

タイトルとURLをコピーしました