Como fazer grep em vários arquivos usando parte do nome do arquivo como padrão?

Como fazer grep em vários arquivos usando parte do nome do arquivo como padrão?

Eu tenho uma pasta que inclui vários arquivos nomeados order[ID].logonde [ID]está uma string, por exemplo

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

Preciso escrever um script no Linux para grepcada arquivo pelo IDnome e enviar o resultado para um arquivo chamado ID.log Exemplo:
For orderID1.log, preciso grep 'ID1' orderID1.log > ID1.log
For orderID2.log, preciso grep 'ID2' orderID2.log > ID2.log
Tentei escrever o script abaixo,

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

O problema aqui é que serei registrado como "orderID1", "orderID2" em vez de "ID1", "ID2". Existe uma maneira simples de fazer isso no Linux?

Responder1

Você terá que extrair a IDsubstring dos nomes dos arquivos. Uma maneira de fazer isso é através da expansão de parâmetros, por exemplo, ${var:offset:length}no seu caso varé filename, offset é 5( order) e length é ${#f}-9(ou seja, comprimento total ${#f}menos o comprimento combinado de ordere .logque são 9caracteres):

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

ou se você preferir uma linha:

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

Alternativamente, você pode usar awkpara aplicara mesma ação para vários arquivos:

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

Isso faz todos os arquivos com uma awkinvocação, evitando o loop do shell. Em uma linha:

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

informação relacionada