
フォルダには、文字列であるorder[ID].log
名前の付いた複数のファイルが含まれています。[ID]
orderID1.log
orderID2.log
orderID3.log
orderID4.log
...
grep
Linuxで各ファイルにスクリプトを記述しID
、結果をという名前のファイルに出力する必要がありますID.log
。例:
の場合orderID1.log
、 の場合、 が必要です。grep 'ID1' orderID1.log > ID1.log
の場合orderID2.log
、 が必要ですgrep 'ID2' orderID2.log > ID2.log
。以下のスクリプトを記述しようとしました。
for i in ORDER*.log
do
grep 'i' order$i > $i.log;
done
ここでの問題は、「ID1」、「ID2」ではなく、「orderID1」、「orderID2」として記録されることです。 Linux でこれを行う簡単な方法はありますか?
答え1
ID
ファイル名から部分文字列を抽出する必要があります。これを行う 1 つの方法は、パラメータ展開を使用することです。${var:offset:length}
たとえば、この場合、var
はf
ilename、オフセットは5
( order
)、長さは${#f}-9
(つまり、${#f}
合計長から と の合計order
長 (文字数) を引いた値).log
です9
。
for f in order*.log
do
ID=${f:5:${#f}-9}
grep -- "$ID" "$f" > "$ID".log
done
またはワンライナーを好む場合は:
for f in order*.log; do ID=${f:5:${#f}-9}; grep -- "$ID" "$f" >" $ID".log; done
あるいはawk
、複数のファイルに対して同じアクションを実行する:
awk '
FNR==1{
if(fname)close(fname)
id=substr(FILENAME, 6, length(FILENAME)-9)
fname=id".log"
}
$0 ~ id{
print > fname
}
' order*.log
awk
これは、シェル ループを回避して、1 回の呼び出しですべてのファイルを実行します。1 行で次のようになります。
awk 'FNR==1{if(f)close(f);id=substr(FILENAME, 6, length(FILENAME)-9);f=id".log"} $0~id{print > f}' order*.log