
Eu tenho uma pasta que inclui vários arquivos nomeados order[ID].log
onde [ID]
está uma string, por exemplo
orderID1.log
orderID2.log
orderID3.log
orderID4.log
...
Preciso escrever um script no Linux para grep
cada arquivo pelo ID
nome 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 ID
substring 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
é f
ilename, offset é 5
( order
) e length é ${#f}-9
(ou seja, comprimento total ${#f}
menos o comprimento combinado de order
e .log
que são 9
caracteres):
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 awk
para 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 awk
invocaçã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