Что на самом деле означает "-n" в sed? - PullRequest
6 голосов
/ 04 мая 2011

Согласно http://linux.about.com/od/commands/l/blcmdl1_sed.htm

подавить автоматическую печать пространства шаблона

Я протестировал с или без -n, sed будет выдавать тот же результат

Я не понимаю, что такое пространство.

Ответы [ 4 ]

22 голосов
/ 04 мая 2011

Sed имеет два места для хранения текста: шаблонное пространство и пространство для хранения. Пространство шаблона - это место, где каждая строка помещается для обработки командами sed; место для хранения - это вспомогательное место для размещения текста, который вы захотите использовать позже. Вы, вероятно, будете использовать только пространство шаблона.

Прежде чем sed отправится на обработку строки, он помещается в пространство шаблона. Затем sed применяет все команды (например, s///) к пространству шаблона и по умолчанию выводит полученный текст из пространства шаблона. Предположим, у нас есть файл myfile со строкой вроде:

The quick brown fox jumps over the lazy dog.

Запускаем следующую команду:

sed 's/fox/coati/;s/dog/dingo/' myfile

Sed будет применять s/fox/coati/, а затем s/dog/dingo/ для каждой строки файла - в данном случае, единственную, которую мы показали выше. Когда это произойдет, он поместит строку в пространство шаблона, которая будет иметь следующее содержимое:

The quick brown fox jumps over the lazy dog.

Затем sed выполнит первую команду. После того, как sed выполнит команду s/fox/coati/, содержимое пространства шаблона будет:

The quick brown coati jumps over the lazy dog.

Затем sed применит вторую команду, которая будет s/dog/dingo/. После этого содержимое шаблона пространства будет:

The quick brown coati jumps over the lazy dingo.

Обратите внимание, что это происходит только в памяти - сейчас ничего не печатается.

После того, как все команды были применены к текущей строке, по умолчанию , sed получит содержимое пространства шаблона и выведет его на стандартный вывод. Однако, когда вы указываете -n в качестве опции для sed, вы просите, чтобы sed не выполнял этот последний шаг , за исключением случаев, когда явно требуется . Итак, если вы запустите

sed -n 's/fox/coati/;s/dog/dingo/' myfile

ничего не будет напечатано.

Но как вы могли явно запросить sed напечатать пространство шаблона? Ну, вы можете использовать команду p. Когда sed найдет эту команду, она немедленно напечатает содержимое пространства шаблона. Например, в приведенной ниже команде мы просим sed напечатать содержимое пространства шаблона сразу после первой команды:

sed -n 's/fox/coat/;p;s/dog/dingo/' myfile

Результат будет

$ sed -n 's/fox/coati/;p;s/dog/dingo/' myfile 
The quick brown coati jumps over the lazy dog.

Обратите внимание, что заменяется только fox. Это происходит потому, что вторая команда не была выполнена до печати пространства шаблона. Если мы хотим напечатать пространство шаблона после обеих команд, мы просто ставим p после второй:

sed -n 's/fox/coati/;s/dog/dingo/;p' myfile

Другой вариант, если вы используете команду s///, - передать флаг p в s///:

sed -n 's/fox/coati/;s/dog/dingo/p' myfile 

В этом случае строка будет напечатана только в случае выполнения помеченной замены . Это может быть очень полезно!

8 голосов
/ 04 мая 2011

Просто попробуйте sed ничего не делать:

sed '' file

и

sed -n '' file

Первый напечатает весь файл, а второй НЕ будет печатать ничего.

3 голосов
/ 04 мая 2011

Это переводит sed в тихий режим, где sed будет подавлять весь вывод, кроме случаев, когда это явно указано командой p:

   -n 
   --quiet 
   --silent
          By default, sed will print out the pattern space at
          the  end  of  each cycle through the script.  These
          options disable this automatic  printing,  and  sed
          will  only  produce  output when explicitly told to
          via the p command.

Примером этого может быть, если вы хотите использовать sed для имитации действий grep:

$echo -e "a\nb\nc" | sed -n '/[ab]/ p'
a
b

без -n вы получите вхождение c (и два вхождения a и b)

1 голос
/ 04 мая 2011
$ echo "a b c d" | sed "s/a/apple/"
apple b c d

Пространство шаблона печатается неявно.

$ echo "a b c d" | sed -n "s/a/apple/"

Нет вывода.

$ echo "a b c d" | sed -n "s/a/apple/p"
apple b c d

Явно печатать пространство шаблона.

...