Первый член удаляет строки с символом «#» в начале.
Непонятно, почему вы хотите, чтобы два термина соответствовали параметру и конечному материалу (почему не один?).
Не ясно, хотите ли вы, чтобы совпадающие строки были напечатаны или нет.
И не ясно, что вы можете получить состояние выхода из sed, указывающего, соответствуют ли какие-либо строки образцу или нет - вам говорят, удалось ли ему выполнить скрипт и открыть все файлы, но это все. Со всеми этими предостережениями:
sed -n '/^#/d;/param=a b c d e f g z x w/p' somefile
Это печатает строки, которые совпадают, игнорируя (-n
) те, которые не соответствуют.
Если вокруг знака '=' разрешены пробелы, вы можете изменить шаблон поиска так, чтобы:
sed -n '/^#/d;/param *= *a b c d e f g z x w/p' somefile
Не ясно, является ли интервал внутри части 'value' критическим; если это не так, вы можете использовать соответствующие термины '*
' (пробел, пробел, звезда; редактор разметки снова работает слишком усердно), чтобы учесть переменный пробел.
Однако, если вы хотите иметь статус grep-like, вам, вероятно, нужно использовать grep
. Как я уже отмечал, sed
не возвращает статус для 'шаблон найден' или 'шаблон не найден', потому что это не то, чем он занимается.
Если вы действительно хотите, чтобы sed
выполнил два совпадения, вам нужно приступить к групповым операциям, которые больше не являются однострочным сценарием.
sed -n '/^#/d;/param/{
/a b c d e f g z x w/p
}' somefile
Это говорит:
- Удалить строки, начинающиеся с '#'.
- Когда вы найдете строку, содержащую «param»,
- Выполните отдельное совпадение для строки 'a b c ...', печатая результат, только если он найден.
NB: как написано, первое совпадение с шаблоном также найдет 'xyz = param' и 'parameter = a b c'; если это не то, что вы хотите, измените шаблон соответствующим образом. Второй шаблон также найдет «g h i a b c d ... x w»; если это не то, что вам нужно, вы должны соответствующим образом изменить его.
Я думаю, вам лучше использовать sed, чтобы убрать комментарий и пустые строки, а затем использовать вашу последовательность grep, чтобы найти ваши значения. Вы должны использовать GNU grep
; Стандартные для POSIX версии grep
на других компьютерах (Solaris, AIX, HP-UX и т. Д.) Не поддерживают параметр -w
. Даже с помощью последовательности grep вы не различаете такие строки, как:
param=a b c d e f g z x w
a b c d e f g z x w=param
Кроме того, ни один из них не позволяет вводить пробелы перед именем параметра, и ни один из них не позволяет использовать табуляции вместо пробелов. Кроме того, должно быть место для подозрений, что даже если имя параметра является фиксированным, значение может иногда меняться; превращение этого в пригодный для использования сценарий оболочки (который вызывает sed, grep или оба) добавляет к деталям, которые нужно рассмотреть.
- Поиск в заданных файлах (аргументы 3 и далее) записей общего вида «имя = значение», где имя - это аргумент 1, а значение - это аргумент 2, игнорируя строки комментариев, начинающиеся с «#», и разрешая интервал переменных (но без вкладок) вокруг имени и равных; не должно быть данных до или после значения.
Это приводит к:
if [ $# -lt 3 ]; then echo "Usage: $0 name value file [...]" 1>&2; exit; fi
name=$1
value=$2
shift 2
sed -n -e '/^#/d' -e "/ *$name *= *$value *$/p" "$@"
Теперь, если этот скрипт называется paramfinder
, я могу написать:
paramfinder param 'a b c d e f g z x w' somefile
Я также могу написать:
paramfinder param '.*a b c d *e f g *z x w.*' somefile
Обратите внимание, что я передал метасимволы регулярных выражений в скрипт sed в значении.
Обратите внимание, что он сломается, если я пройду:
paramfinder passwordfile /etc/passwd somefile
Это потому, что косые черты в "/ etc / passwd" нарушают соответствие регулярного выражения.
В зависимости от ваших реальных требований (это домашняя работа или производственная проблема - и насколько она должна быть надежной), вы можете рассмотреть возможность перехода на Perl где-то здесь (или на Python или на другой подобный язык сценариев по вашему выбору).