¿Cómo grep varios archivos usando parte del nombre del archivo como patrón?

¿Cómo grep varios archivos usando parte del nombre del archivo como patrón?

Tengo una carpeta que incluye varios archivos llamados order[ID].logdonde [ID]hay una cadena, por ejemplo

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

Necesito escribir un script en Linux para grepcada archivo por IDsu 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 IDsubcadena 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 vares fel 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 ordery .logcuáles son 9los 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 awkpara 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 awkinvocació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

información relacionada