Почему я должен вызывать sed второй раз после замены пробелов символами новой строки?

Если вы хотите запустить mplayer, убить его через 15 секунд и повторять, пока сам скрипт не будет убит, вы можете сделать что-то вроде этого:

#!/bin/sh

while true; do
  ## launch mplayer in the background
  mplayer -loop 0 -rootwin -ao null -noconsolecontrols -fs VIDEOPATH &
  ## wait for 15 seconds
  sleep 15
  ## kill the 1st backgrounded job of this subshell
  kill %1
done
1
25.01.2020, 01:17
2 ответа

Каждое sedвыражение действует на все пространство шаблонов. В начале цикла строка считывается в пространство шаблонов, затем sedприменяет каждое заданное выражение к этим данным.

Во втором варианте вашего кода вы вставляете новые строки в пространство шаблонов с заменой. Второе выражение, /^$/d, по-прежнему будет воздействовать на пространство шаблонов в целом, а не на каждую отдельную строку в пространстве шаблонов, что означает, что шаблон не будет соответствовать (, так как буфер не -пуст ), и пространство шаблона не будет удалено. Замена /^$/dна s/\n\{2,\}//gудалит любой набор из двух или более последовательных символов новой строки -(, это создаст пустые строки в выводе ), что будет работать.

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

Вкратце :Добавление новых строк в пространство шаблонов не заставит sedпересматривать каждую сгенерированную строку как отдельный вход для остальных выражений.


Альтернативное решение:

od -v -A n -t o1 -- /tmp/file |
sed -e 's/ \{2,\}//g' -e 'y/ /\n/'

Первое sedвыражение, s/ \{2,\}//g,избавляется от любого выполнения двух или более последовательных пробелов, а затем второе выражение преобразует оставшиеся пробелы в новые строки(\nразрешено с помощью команды yдаже в POSIXsed).

Или вы можете удалить все боковые пробелы перед преобразованием всех оставшихся пробелов в новые строки:

od -v -A n -t o1 -- /tmp/file |
sed -e 's/^ *//' -e '$s/ *$//' -e 'y/ /\n/'

(Обратите внимание, что только последняя строка вывода из odможет иметь завершающие пробелы, поэтому я использую $в качестве адреса для второго выражения.)

Или это может быть проще сawk:

od -v -A n -t o1 -- /tmp/file |
awk '{ for (i = 1; i <= NF; ++i) print $i }'
4
27.01.2020, 23:17

Это потому, что пустые строки существуют только в выходном файле после того, как были сделаны замены. Почему бы и нет

od -v -An -to1 -w1 -- file 

?

0
27.01.2020, 23:17

Теги

Похожие вопросы