Как совместить точную строку с помощью `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` как я могу поместить один символ« & »между символами в строке?
- Bash - Замена случайного числа между кавычками
Мне удалось прокрутить каждый идентификатор и сформировать следующую команду для каждого идентификатора, как требуется.
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
- загрузить весь файл
- чистый раздел не является частью группы id (рекурсивный)
- просто введите значение содержания NAME в группе
- распечатать результат
вы можете распечатать те строки, которые содержат соответствующий шаблон, используя sed:
sed -n '/pattern/p' Filename
-
-n
– эти параметры отключают эту автоматическую печать, и sed только производит вывод, когда явно передается через командуp
. -
p
– печать