Как совместить точную строку с помощью `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

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

  • Число новых строк в строке как целое
  • grep инвертированное соответствие по строке, удовлетворяющей шаблону
  • Обрезать последние символы из строки
  • Извлечение подстроки из переменной среды
  • Подстрока grep между кавычками
  • заменяя многострочную строку другой многострочной строкой, используя sed
  • Как проверить строку в строке с помощью оператора if?
  • Добавить разделитель тысяч в число
  • 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 – печать

    Linux и Unix - лучшая ОС в мире.