#shell #awk #grep
#оболочка #awk #grep
Вопрос:
У меня в файле будет много данных, нужно напечатать точное ключевое слово в следующем формате : Filename : Keyword : line number
[Примечание: необходимо выполнить рекурсивный поиск ключевого слова по всему каталогу]
Например: я хочу выполнить поиск по ключевому слову: abcxyz
Данные в файле, как показано ниже
abcxyz.fgh
gfhj.abcxyz
i have a book with name abcxyz.sh
where is my brother called : abcxyz.fsdghj raju how are you
afsgdjj kllf
ghjakl ra jksu ldlahlalfb afhkflkaf dbllf jll afl;bnhafl
Когда я использую следующую команду: grep "abcxyz" *.*
она печатает всю строку, которая мне не нужна
Ожидаемый результат :
Filename : abcxyz.fgh : line number
Filename : gfhj.abcxyz : line number
Filename : abcxyz.sh : line number
Filename : abcxyz.fsdghj : line number
Ответ №1:
Вот и все
grep -roHn "S*Your_text_hereS*" *
Теги
-r: рекурсивно в каталоге
-o: только совпадающая часть
-H: с именем файла
-n: с номером строки
затем изменил регулярное выражение, чтобы включить все символы, кроме пробела, табуляции и новой строки, вокруг вашего совпадающего шаблона S
. Примечание: если вам нужны только алфавиты и цифры и вместо них не используются специальные символы w
.
а затем последний ‘*’, чтобы указать на поиск каждого файла и папки в вашем текущем каталоге. Итак, чтобы использовать эту команду сначала cd
в требуемом каталоге.
Комментарии:
1. Забавно, вы интерпретировали вопрос противоположным образом, как я это сделал. Я могу это понять. Один из наших ответов, вероятно, окажется не тем, что хочет OP. Я был полностью уверен в своем чтении. Но, вероятно, и вы тоже. Давайте посмотрим.
2. Похоже, вы правильно его прочитали. Получайте удовольствие.
3. Почему вы используете
*
as path, а.
не для простого «здесь»?4. Я использовал
*
по привычке. Обычно мне требуется выбирать файлы с определенным форматом, например ‘* .txt’..
полностью работает для этого случая.5. Вы должны использовать
S
вместоw
, поскольку OP хочет сопоставить больше, чем просто символы, составляющие слово, например.
, см. ожидаемый результат. Вы также должны упомянуть, что для этого требуется GNU grep.
Ответ №2:
Это должно быть задачей awk
, не могли бы вы попробовать следующее, написанное и протестированное с показанными примерами в GNU awk
. Пожалуйста, укажите абсолютный путь вместо .
, чтобы запустить его для любого каталога в команде find.
Вывод должен быть filename : matched string(s) : line number
для всех файлов.
Вы можете запустить следующую find
команду:
find . -type f -exec awk -f script.awk {}
Где script.awk
следующим образом:
cat script.awk
BEGIN{ OFS=" : " }
NF{
val=""
for(i=1;i<=NF;i ){
if($i~/abcxyz/){
val=(val?val OFS:"")$i
}
}
if(val){
print FILENAME,val,FNR
}
}
Для ваших показанных образцов (с учетом пустых строк в нем) вывод образца будет следующим.
Input_file : abcxyz.fgh : 1
Input_file : gfhj.abcxyz : 3
Input_file : abcxyz.sh : 5
Input_file : abcxyz.fsdghj : 7
Объяснение: добавление подробного объяснения выше.
BEGIN{ OFS=" : " } ##Setting OFS to space colon space in BEGIN section of this program.
NF{ ##Checking condition if line is NOT empty then do following.
val=""
for(i=1;i<=NF;i ){ ##Traversing through all field values here.
if($i~/abcxyz/){ ##checking condition if field is matching abcxyz then do following.
val=(val?val OFS:"")$i ##Creating val which has value of current field and keep adding it.
}
}
if(val){ ##Checking condition if val is NOT NULL then do following.
print FILENAME,val,FNR ##Printing FILENAME val and FNR here.
}
}
'