Как выполнить grep нескольких файлов, используя часть имени файла в качестве шаблона?

Как выполнить grep нескольких файлов, используя часть имени файла в качестве шаблона?

У меня есть папка, которая содержит несколько файлов, в названии order[ID].logкоторых [ID]есть строка, например

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

Мне нужно написать скрипт в Linux для grepкаждого файла, указав IDв его имени и вывести результат в файл с именем ID.log Пример:
Для orderID1.log, мне нужно grep 'ID1' orderID1.log > ID1.log
Для 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}в вашем случае varэто filename, offset это 5( order) и length это ${#f}-9(то есть общая длина ${#f}минус объединенная длина orderи .logwhich это 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вызовом, избегая цикла оболочки. В одной строке:

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

Связанный контент