ファイル名の一部をパターンとして使用して複数のファイルをgrepする方法は?

ファイル名の一部をパターンとして使用して複数のファイルをgrepする方法は?

たとえば、文字列がorder[ID].logどこにあるかという名前の複数のファイルを含むフォルダがあります。[ID]

orderID1.log
orderID2.log
orderID3.log
orderID4.log
...

Linuxでは、grepファイル名ごとに各ファイルにスクリプトを作成し、IDその結果をID.log ファイル名として出力する必要があります。例:
For orderID1.log, I need grep 'ID1' orderID1.log > ID1.log
For orderID2.log, I needgrep '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}あなたの場合はilename)を介して拡張することです。オフセットはvar()で、長さは次のとおりです(つまり、合計の長さから合計の結合長を引いた値、文字は次のようになります)。f5order${#f}-9${#f}order.log9

for f in order*.log                                                 
  do 
    ID=${f:5:${#f}-9}
    grep -- "$ID" "$f" > "$ID".log
  done

または1行を好む場合:

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

すべてのファイルを完了するには1回の呼び出ししか必要とされず、awkシェルループが防止されます。一行:

awk 'FNR==1{if(f)close(f);id=substr(FILENAME, 6, length(FILENAME)-9);f=id".log"} $0~id{print > f}' order*.log

関連情報