
У меня есть папка, которая содержит несколько файлов, в названии 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
это f
ilename, offset это 5
( order
) и length это ${#f}-9
(то есть общая длина ${#f}
минус объединенная длина order
и .log
which это 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