如何使用文件名的一部分作为模式来 grep 多个文件?

如何使用文件名的一部分作为模式来 grep 多个文件?

我有一个文件夹,其中包含几个名为order[ID].logwhere [ID]is a string 例如的文件

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

我需要在 Linux 中grep按文件名中的 向每个文件写入一个脚本ID,并将结果输出到名为ID.log 示例的文件中:
For orderID1.log,我需要grep 'ID1' orderID1.log > ID1.log
For orderID2.log,我需要grep 'ID2' orderID2.log > ID2.log
我尝试编写下面的脚本,

for i in ORDER*.log 
do 
grep 'i' order$i > $i.log;
done

这里的问题是我将被记录为“orderID1”,“orderID2”而不是“ID1”,“ID2”。在linux下有没有简单的方法可以做到这一点?

答案1

您必须ID从文件名中提取子字符串。一种方法是通过参数扩展,例如${var:offset:length}在您的情况下varfilename,偏移量是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调用即可完成所有文件,从而避免 shell 循环。一行:

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

相关内容