シェルでsedを使ってパス文字列からディレクトリ名,ファイル名,拡張子を抽出する

2023-03-27Bash,Linux

はじめに

ネタが無いのでありふれたネタを取り上げてみました。

シェルでパス文字列をディレクトリ名、ファイル名、拡張子に分割する方法はいくつかあります。

過去に投稿した Bash 組み込みの正規表現機能 を使ったり、Bash の変数を使ったり、 dirname + basename コマンドを使ったり、 grep を使ったり。

今回は sed のみで実現してみます。

検証環境

$ uname -moi
aarch64 aarch64 GNU/Linux

$ head -n 3 /etc/os-release
PRETTY_NAME="Ubuntu Kinetic Kudu (development branch)"
NAME="Ubuntu"
VERSION_ID="22.10"

$ bash -version | head -n 1
GNU bash, バージョン 5.2.0(1)-release (aarch64-unknown-linux-gnu)

$ sed --version | head -n 2
sed (GNU sed) 4.8
パッケージ作成者: Debian

sed を使ったパス文字列分割の正規表現

以下のような sed を使った正規表現を用いて、パス文字列を分割できます。

sed -E 's@^(.*/)(([^.]+)\.?(.*))$@\1 \2 \3 \4@'

実行すると、スペース区切りで 4 つの情報が出力されます。

それぞれ以下のような情報となっています。

  1. 親ディレクトリパス
  2. ファイル名
  3. 拡張子なしファイル名
  4. 拡張子

実行例

$ sed -E 's@^(.*/)(([^.]+)\.?(.*))$@\1 \2 \3 \4@' <<<"/a/b/c/xxx.txt"
/a/b/c/ xxx.txt xxx txt

$ sed -E 's@^(.*/)(([^.]+)\.?(.*))$@\1 \2 \3 \4@' <<<"/yyy.sh"
/ yyy.sh yyy sh

$ sed -E 's@^(.*/)(([^.]+)\.?(.*))$@\1 \2 \3 \4@' <<<"/a/b/c/zzz.1.2.js"
/a/b/c/ zzz.1.2.js zzz 1.2.js

$ sed -E 's@^(.*/)(([^.]+)\.?(.*))$@\1 \2 \3 \4@' <<<"/a/b/c/Dockerfile"
/a/b/c/ Dockerfile Dockerfile
  • ドット . が 2 つ以上存在する場合には、一番最初のドットから後ろを拡張子として認識しています。

  • 拡張子がない場合には、4 列目の情報が表示されません。

ひとこと

ほぼ以下の内容の丸パクリですね。

Bash 組み込みの正規表現機能を利用してファイルパスを要素に分割してみる | ゲンゾウ用ポストイット

2023-03-27Bash,Linux