Как совместить точную строку с помощью `sed`? Но не его часть.

У меня есть входной файл FILE1.TXT, как показано ниже.


11 id1 12 13 AGE = 20 14 NAME = NAME1 15 16 id2 17 18 AGE = 30 19 NAME = NAME2 . . . 110 idXYZ 111 112 AGE = AGEXYZ 113 NAME = NAMEXYZ 114 115 idZZZ 116 

Я хочу искать все поля, относящиеся к определенному идентификатору, и получить значение для NAME

Мне удалось прокрутить каждый идентификатор и сформировать следующую команду для каждого идентификатора, как требуется.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'

Проблема здесь в том, что я получаю выход NAME1 , в дополнение к этому, я также получаю NAMEXYZ .

Что нужно изменить, чтобы получить только NAME1, но не NAMEXYZ ?

В качестве обходного пути работают следующие команды.

sed -n '/11/,/14/p' FILE1.TXT | grep NAME | awk -F "= " '{print $2}'|head -1

Есть ли какой-нибудь «переключатель» или я что-то упускаю?

7 Solutions collect form web for “Как совместить точную строку с помощью `sed`? Но не его часть.”

Если вам известны номера строк, которые вы хотите найти (как предлагает ваш Q), затяните регулярное выражение так, чтобы вы не соответствовали нежелательным линиям.

Например, измените:

 sed -n '/11/,/14/p' | grep NAME | awk -F "= " '{print $2}' 

в

 sed -n '/^11 /,/^14 /p' | grep NAME | awk -F "= " '{print $2}' 

« ^ Будет соответствовать началу строки и пробелу после номера, что гарантирует соответствие определенного номера строки, и вы не будете обрабатывать нежелательные блоки.

Вы можете использовать AWK

 awk 'NR>=13 && NR<=17 && /NAME/{print $NF}' infile 

Это будет выглядеть линиями между 13 и 17, затем поиск имени и, если совпадение, тогда он будет печатать последнее слово из Name = LastWord

sed – не лучший инструмент для этой работы. Используйте awk, где вы можете указать идентификатор, который вы ищете, и распечатать следующее NAME, которое появляется.

 awk -v id="id2" ' $NF == id {have_id = 1} have_id && $0 ~ /NAME/ {print $NF; exit} ' filename 

Используйте границы слов:

 grep '\bNAME1\b' 

будет соответствовать NAME1 а не NAME1XYZ или XYZNAME1 .

По аналогии,

 sed -n '/11\b/,/14\b/p' 

не будет соответствовать линиям, содержащим 111 и 142 .


EDIT: Кажется, что цифры во входном файле являются номерами строк. Если это так, вы можете просто сказать:

 sed '11,14!d' 

для получения желаемых строк.

Для этого вам не нужен какой-либо другой инструмент, sed будет легко обрабатывать его целиком.

 sed -nr '/11/,/14/{s/^.*NAME =\s*(\S*).*$/\1/p}' <$infile 

Это должно предоставить вам только первую последовательность символов без пробелов, следующих за фразой «NAME =» для каждой строки, в которой эта фраза находится между строками 11 и 14 любого входного файла sed .

родовая версия, не основанная на номере строки, но ссылка id

 sed -n '1h;1!H; $ { x s/.*/&\^J/ : clean # put your ID pattern here in place of id9 s/.*\(id9 *\n.*\)id[0-9]\{1,\} *\n.*/\1/ t clean s/.*NAME = \([^[:cntrl:]]*\)\n.*/\1/ p }' YourFile 
  1. загрузить весь файл
  2. чистый раздел не является частью группы id (рекурсивный)
  3. просто введите значение содержания NAME в группе
  4. распечатать результат

вы можете распечатать те строки, которые содержат соответствующий шаблон, используя sed:

 sed -n '/pattern/p' Filename 
  • -n – эти параметры отключают эту автоматическую печать, и sed только производит вывод, когда явно передается через команду p .

  • p – печать

  • Проверьте, содержит ли строка строку подстроки
  • Bash: Родной способ избавиться от цитаты вокруг каждого элемента массива
  • Как я могу получить доступ к столбцу строки из строки?
  • Проверьте, содержит ли переменная оболочки абсолютный путь
  • Трубы Дженкинса, ш, кавычки и пробелы
  • Получить конкретное слово и следующий текст
  • добавьте подкаталоги в $ PATH в bash, используя find
  • Zsh скрипт, как конкатенировать элементы массива со строкой
  • Sed - замена строк с помощью группировок
  • Добавить (изменить) каждый элемент массива через расширение параметра (т. Е. Без printf)?
  • Невозможно сравнить результат lsb_release с строкой в ​​Bash
  • Число новых строк в строке как целое
  • Linux и Unix - лучшая ОС в мире.