【Shell】文字列の展開・切り出し・置換:ブレース展開/チルダ展開/ファイル名のみ取得/ディレクトリ名のみの取得

■ブレース展開:{ }

▼カンマ区切り{文字列1,文字列2,文字列3}による展開

文字列の出力や、ディレクトリ作成などを行う際に、文字列+{文字列1,文字列2,文字列3}+文字列のように、カンマ区切りで{ }を指定すると、{ }の文字列が前後の文字列と組み合わされて取得できる。

▼サンプルコード

# 名前表示:{01,02,aaa,bbb,(空文字)}
echo hogehoge_{01,02,aaa,bbb,}file

▼実行結果

hogehoge_01file hogehoge_02file hogehoge_aaafile hogehoge_bbbfile hogehoge_file

同一階層に複数のディレクトリを作成する場合や、lsコマンドでも使用可能である。

▼サンプルコード

# ディレクトリ作成:{test1,test2,tmp}
mkdir -m 777 /work/{test1,test2,tmp}

# フォルダの存在確認:{test1,test2,tmp}
ls /work/{test1,test2,tmp}

▼実行結果

/work/test1:

/work/test2:

/work/tmp:

▼連続した文字/数字の指定{From..To}による展開

ブレース展開において、{ }ないに「..」を指定すると、文字/数字のFrom..Toを指定することができる。

▼サンプルコード

# 名前表示:{from..to}数字
echo hogehoge_{01..05}file

# 名前表示:{from..to}1個飛ばし
echo hogehoge_{1..10..2}file

# 名前表示:{from..to}文字
echo hogehoge_{a..e}file

▼実行結果

hogehoge_1file hogehoge_2file hogehoge_3file hogehoge_4file hogehoge_5file
hogehoge_1file hogehoge_3file hogehoge_5file hogehoge_7file hogehoge_9file
hogehoge_afile hogehoge_bfile hogehoge_cfile hogehoge_dfile hogehoge_efile

■チルダ展開:~

チルダを指定すると、ユーザ名のホームディレクトリを参照することができる。

▼サンプルコード

# ユーザホームディレクトリ直下(/home/"ユーザ名")にフォルダを作成
mkdir -m 777 ~/testdir

# ユーザホームディレクトリ直下(/home/"ユーザ名")の情報を取得
ls ~

▼実行結果

testdir

■変数に格納した文字列の展開(切り出し)

▼「:?」による、変数の設定判定

任意の変数に値が設定されているか判別する際は、変数名に「:?」を使用することで判別することができる。

▼サンプルコード(エラー)

# 変数に値がセットされているかチェック(セットされていないからエラー)
echo ${tmp_name:?}

▼実行結果

-bash: tmp_name: パラメータが null または設定されていません

▼サンプルコード(正常系)

# 変数に値をセット
tmp_name=hoge1_hoge2_hoge3

# 変数に値がセットされているかチェック(セットされているからOK)
echo ${tmp_name:?}

▼実行結果

hoge1_hoge2_hoge3

▼文字列の切り出し

変数に格納されている文字列のうち、何バイト目から何文字など、指定したバイト数に文字列を切り出す場合は、変数名にコロン( : )を使用して、切り出す位置とバイト数を指定する。
また、格納した変数について、文字数を取得する場合は、変数名の先頭に「#」をつける。

▼サンプルコード

# 変数に値をセット
tmp_name=hoge1_hoge2_hoge3

# 文字列の切り出し:2文字目以降の値を取得
echo ${tmp_name:1}

# 文字列の切り出し:末尾5文字を取得
echo ${tmp_name: -5}

# 文字列の切り出し:7文字目から5文字を取得
echo ${tmp_name:6:5}

# 文字数を出力
echo ${#tmp_name}

▼実行結果

oge1_hoge2_hoge3
hoge3
hoge2
17

ちなみに、変数に格納した値が配列の場合は、以下のように指定する。

▼サンプルコード

# 配列をセット
tmp_array=(aa bb cc dd)

# 2つ目の要素から出力
echo ${tmp_array[@]:1}

# 2つ目の要素から2つの要素を出力
echo ${tmp_array[@]:1:2}

▼実行結果

bb cc dd
bb cc

▼文字列(ファイル名)の切り出しと置換

ファイル名を変数に格納し、拡張子名のみ出力したい場合は、「変数名#*.」で最短の拡張子が取得でき、「変数名##*.」で最長の拡張子名を取得できる。
「#*.」は変数に格納した文字列について、最初に「 . 」が現れたところまで削除するという意味となる。

▼サンプルコード

# 事前準備:変数名の取得
file_name=tmp.tar.gz

# 拡張子の取得(最短)
echo ${file_name#*.}

# 拡張子の取得(最長)
echo ${file_name##*.}

▼実行結果

tar.gz
gz

ファイル名を変数に格納し、ファイル名のみ出力したい場合は、「変数名%.*」で最短の拡張子以前の値が取得でき、「変数名%%.*」で最長の拡張子以前の値を取得できる。
「%.*」は変数に格納した文字列について、最初に「 . 」が現れたところ以降を削除するという意味となる。

▼サンプルコード

# 事前準備:変数名の取得
file_name=tmp.tar.gz

# 拡張子の除去(最短)
echo ${file_name%.*}

# 拡張子の除去(最長)
echo ${file_name%%.*}

▼実行結果

tmp.tar
tmp

変数に格納した文字列について、文字列を置換したい場合は、「変数名/置換前文字列/置換後文字列」で置換することができる。
また、対象の置換前文字列をすべて置換する場合は、「変数名//置換前文字列/置換後文字列」と記載する。

▼サンプルコード

# ドッド->アンスコに置換(1つ目のドット)
echo ${file_name/./_}

# ドッド->アンスコに置換(すべて)
echo ${file_name//./_}

# 拡張子の変換->txtに置換
echo ${file_name/.*/.txt}

▼実行結果

tmp_tar.gz
tmp_tar_gz
tmp.txt

▼文字列(ファイル名:フルパス)の切り出し

ファイル名(フルパス)の文字列が格納された変数について、ファイル名のみを出力したい場合は、「変数名##*/」を指定し、ディレクトリ階層のみを表示したい場合は、「変数名%/*」を指定する。
「変数名##*/」は、末尾の[ / ]以前の文字列を削除しており、「変数名%/*」は末尾の[ / ]以降を削除している。

▼サンプルコード

# ファイルパス名(フルパス)の操作
tmp_file_path=/work/tmp/tmp.tar.gz

# ファイル名のみを表示
echo ${tmp_file_path##*/}

# パス名のみを表示
echo ${tmp_file_path%/*}

▼実行結果

tmp.tar.gz
/work/tmp

▼日付出力コマンド(date)の結果を文字列にセット

日付を出力するdateコマンドの結果を文字列に反映させるには、$(date +%Y%m%d)のようにカッコで括るか、`date +%Y%m%d`のようにバックフォード[ ` ]で括る。
日付(YYYYMMDD)を文字列にセットすることで、日次のジョブで作成するファイルや作業フォルダ作成に便利である。

▼サンプルコード

# 日付の表示(YYYYMMDD)
date +%Y%m%d

# ファイル名に日付をつける。
touch tmp_$(date +%Y%m%d).txt

ls tmp_$(date +%Y%m%d).txt

▼実行結果

tmp_20211220.txt

コメント