Можно снабдить префиксом большинство команд sed адрес для ограничения строк, к которым они применяются. Адрес может быть номером строки или regex, разграниченным /
.
cat INPUT | sed '/Select ASDF/ s=sdfg=XXXX='
Как упомянутый Peter. O, команда, как записано выше заменит первым вхождением любого sdfg
в строке, содержащей Select ASDF
. Если необходимо заменить точным совпадением sdfg
только в случае это находится в четвертом столбце, необходимо пойти этим путем:
cat INPUT | sed 's/\(^Select ASDF [^ ]* \)sdfg /\1XXXX /'
В дополнение к документации jordanm указывает на, я хочу удостовериться, что исправил неправильное представление, проиллюстрированное в Вашем вопросе — выполненная программа не обрабатывает перенаправления. Это едва даже знает о них. Оболочка обрабатывает перенаправления.
Программа запущена с тремя открытыми файлами: stdin (#0), stdout (#1), и stderr (#2). Если Вы просто запустите программу от своего приглашения оболочки, то они будут подключены к Вашему оконечному устройству, таким образом, программа считает то, что Вы вводите (stdin), и печать производит (stdout) и ошибки (stderr) к Вашему терминалу.
Как пример, я просто работаю cat
в терминале (который tty
говорит /dev/pts/31
). Я могу проверить, с какими файлами это имеет открытый lsof
:
$ lsof -a -p `pidof cat` -d0,1,2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 21257 anthony 0u CHR 136,31 0t0 34 /dev/pts/31
cat 21257 anthony 1u CHR 136,31 0t0 34 /dev/pts/31
cat 21257 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
Действительно, мы видим, что это имеет терминал, открытый для всех трех. Теперь, вместо этого, давайте попробуем довольно глупый вызов кошки: cat < /dev/zero > /dev/null 2>/dev/full
, который перенаправляет все три:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 21838 anthony 0r CHR 1,5 0t0 1030 /dev/zero
cat 21838 anthony 1w CHR 1,3 0t0 1028 /dev/null
cat 21838 anthony 2w CHR 1,7 0t0 1031 /dev/full
Оболочка реализовала те перенаправления путем передачи этих трех устройств как stdin, stdout, и stderr (вместо терминала). Оболочка так же реализует каналы. Давайте попробуем cat | dd > /dev/null
(довольно глупый канал, действительно):
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
cat 22507 anthony 0u CHR 136,31 0t0 34 /dev/pts/31
cat 22507 anthony 1w FIFO 0,8 0t0 56081395 pipe
cat 22507 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
dd 22508 anthony 0r FIFO 0,8 0t0 56081395 pipe
dd 22508 anthony 1u CHR 136,31 0t0 34 /dev/null
dd 22508 anthony 2u CHR 136,31 0t0 34 /dev/pts/31
Заметьте, как оболочка открыла канал, и она использовала его для соединения stdout cat
к stdin dd
. И далее как это соединилось dd
stdout к /dev/null
.
Выполняемые команды действительно не знают о перенаправлениях. Они просто используют stdin, stdout, stderr как нормальный. Это мог все быть терминал, или они могли быть перенаправлены в файл, устройство или возможно канал к другой программе. Или даже сетевой сокет, если Ваши поддержки оболочки это.
Даже наиболее смехотворно сложные конвейеры являются на самом деле просто инструкциями к оболочке о том, как соединить те три дескрипторов файлов прежде, чем выполнить программу.
(ПРИМЕЧАНИЕ: Некоторые программы ведут себя по-другому в случае, где один из тех привязан к терминалу, но это должно обычно быть более удобным для пользователя в интерактивном использовании, Например, ls
переключатели к выводу отдельного столбца и никакому цвету, когда stdout не является терминалом — который обычно является, что Вы хотите, если Вы собираетесь передать его другой программе. Некоторый дескриптор программ, запрашивающий по-другому, если stdin не является терминалом. И так далее.)
Перенаправление происходит сначала в оболочке. В Вашем примере:
cat test.txt > test.txt
Первой вещью, которая происходит, является удар, открывается test.txt
, который усекает файл. Это теперь пусто, прежде cat
выполняется с test.txt
как аргумент.
От раздела перенаправления страницы справочника удара:
Прежде чем команда выполняется, ее ввод и вывод может быть перенаправлен с помощью специальной нотации, интерпретируемой оболочкой. Перенаправление может также использоваться, чтобы открыть и закрыть файлы для текущей среды выполнения оболочки. Следующие операторы перенаправления могут предшествовать или появиться где угодно в рамках простой команды или могут следовать за командой. Перенаправления обрабатываются в порядке, они появляются, слева направо.
Я ничего не вижу в спецификации POSIX, чтобы указать, что она должна произойти сначала, но я не знаю об оболочке, где она не делает.
cat
незаметные работы, и к счастью Вы проиллюстрировали это. – Kent Pawar 14.06.2013, 17:59