よっしー
こんにちは。よっしーです(^^)
今日は、特定のディレクトリ配下にあるファイルで、任意の文字列を一括置換する方法についてご紹介します。
背景
特定のディレクトリ配下にあるファイルで、任意の文字列を一括置換する必要があり、その際に使用した方法を備忘として残しました。
テストデータの作成
下記のテストデータを作成するスクリプトをgen_test.shという名前で作成します。
#!/usr/bin/env bash
sh_name=$(basename "$0")
arg01=$1
log_dir=${sh_name%.sh}
[ ! -e "${log_dir}" ] && mkdir -p "${log_dir}"
LC_CTYPE=C tr -dc 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' < /dev/urandom | head -c 10 > "${log_dir}/${arg01}.log"
このスクリプトを100回実行します。
seq 100 | xargs -P $(nproc) -I{} -t sh -c "bash gen_test.sh {}"
一括置換
下記のコマンドで一括置換しました。
find ./gen_test -type f -name "*.log" -print0 | xargs -0 grep -l 'a' | xargs sed 's/a/ NEW /g'
下記のような出力になっていれば成功です。
% find ./gen_test -type f -name "*.log" -print0 | xargs -0 grep -l 'a' | xargs sed 's/a/ NEW /g'
TxQbPtl NEW Py
8RrzmB NEW VZ5
3D NEW ciE2Zlq
Roy NEW NDlzX5
dzIAQVbQq NEW
wcfuXeBb NEW b
1I8mf NEW iR2j
h3Vg40wfY NEW
IZhQD NEW HOUW
mINL NEW wPg9J
X1rO NEW jJTZL
3x9fc74ez NEW
Ou6Igq7 NEW mb
M4b63I NEW BVq
llh1 NEW LyfKp
siD NEW AyTQfL
解説
このコマンドは、指定されたディレクトリ内の .log
ファイル内で文字列 ‘a’ を検索し、その文字列を ‘NEW’ に置換する操作を行います。
find ./gen_test -type f -name "*.log" -print0
:find
: ファイルやディレクトリを検索するコマンドです。./gen_test
: カレントディレクトリ内のgen_test
ディレクトリを対象とします。この部分を適切なディレクトリパスに変更することもできます。-type f
: ファイルを対象とします(ディレクトリは対象外)。-name "*.log"
: ファイル名が.log
で終わるものを対象とします。-print0
: ファイル名を NULL 文字区切りで表示します。特殊文字を含むファイル名に対応するための設定です。
xargs -0 grep -l 'a'
:xargs
: 前のコマンドの出力を受け取り、指定されたコマンドを実行するためのコマンドです。-0
: NULL 文字区切りの入力を受け取るための設定です。grep -l 'a'
:grep
コマンドを使って、文字列 ‘a’ を含むファイル名を検索します。-l
オプションは、検索対象が見つかったファイル名だけを表示します。
xargs sed 's/a/ NEW /g'
:xargs
: 前のコマンドの出力(’a’ を含むファイル名)を受け取り、指定されたコマンドを実行するためのコマンドです。sed 's/a/ NEW /g'
:sed
コマンドを使って、ファイル内の ‘a’ を ‘NEW’ に置換します。's/a/ NEW /g'
はテキストの置換を行う正規表現です。g
オプションは一行内の全ての一致を置換するためのものです。
要するに、このコマンドは ./gen_test
ディレクトリ内の .log
ファイル内で文字列 ‘a’ を検索し、それをすべて ‘NEW’ に置換します。iオプションを使用して、直接ファイルを変更することも可能です。変更前のファイルをバックアップしてから実行することをお勧めします。
おわりに
今日は、特定のディレクトリ配下にあるファイルで、任意の文字列を一括置換する方法についてご紹介しました。
よっしー
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント