
Tengo una carpeta que incluye varios archivos llamados order[ID].log
donde [ID]
hay una cadena, por ejemplo
orderID1.log
orderID2.log
orderID3.log
orderID4.log
...
Necesito escribir un script en Linux para grep
cada archivo por ID
su nombre y enviar el resultado a un archivo llamado ID.log
Ejemplo:
Para orderID1.log
, necesito grep 'ID1' orderID1.log > ID1.log
Para orderID2.log
, necesito grep 'ID2' orderID2.log > ID2.log
Intenté escribir el siguiente script,
for i in ORDER*.log
do
grep 'i' order$i > $i.log;
done
El problema aquí es que me registrarán como "orderID1", "orderID2" en lugar de "ID1", "ID2". ¿Existe una forma sencilla de hacer esto en Linux?
Respuesta1
Tendrás que extraer la ID
subcadena de los nombres de los archivos. Una forma de hacerlo es mediante la expansión de parámetros, por ejemplo, ${var:offset:length}
en su caso var
es f
el nombre de archivo, el desplazamiento es 5
( order
) y la longitud es ${#f}-9
(es decir, la longitud total ${#f}
menos la longitud combinada de order
y .log
cuáles son 9
los caracteres):
for f in order*.log
do
ID=${f:5:${#f}-9}
grep -- "$ID" "$f" > "$ID".log
done
o si prefieres una sola línea:
for f in order*.log; do ID=${f:5:${#f}-9}; grep -- "$ID" "$f" >" $ID".log; done
Alternativamente, puede utilizar awk
para aplicarla misma acción a múltiples archivos:
awk '
FNR==1{
if(fname)close(fname)
id=substr(FILENAME, 6, length(FILENAME)-9)
fname=id".log"
}
$0 ~ id{
print > fname
}
' order*.log
Esto hace todos los archivos con una sola awk
invocación, evitando el bucle de shell. En una línea:
awk 'FNR==1{if(f)close(f);id=substr(FILENAME, 6, length(FILENAME)-9);f=id".log"} $0~id{print > f}' order*.log