Как найти точное совпадение и распечатать только это совпадение

#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.
  }
}
'