Нет необходимости помещать метку :a
за пределы основной инструкции, и при этом не -e
требуется необходимая опция; наконец, /$/
лишнее (каждая строка имеет символ EOL).
Улучшая другие ответы, каждый получает
sed -i ':a; N; s/\n/ /; ta' file
Что яснее, если написано так:
sed -i ':a
N
s/\n/ /
ta' file
Команда работает следующим образом:
N
добавляет следующую строку к (многострочному) шаблонному пространству, которое уже содержит текущую строку;
s/\n/ /
заменить символ новой строки, \n
сгенерированный N
с помощью пробела
;
ta
переходит к строке сценария, следующей за меткой, :a
до тех пор, пока замена на шаге 2 прошла успешно , т. е. если замена произошла, выполнение переходит на шаг 1 без «удара» по концу сценария, т.е. без чтения другой строки ввода.
Обратите внимание на следующее;
sed
читает строки входного файла по порядку, начиная с 1-й строки ;
:a
это просто метка, а не команда для выполнения;
N
в принципе выполняется на любой строке, но
s/\n/ /
(в принципе выполняется на любой строке) успешно на любой строке, кроме последней , поэтому
ta
делает конец скрипта достижимым только тогда, когда читается последняя строка ввода (единственная строка, где происходит s
сбой), поэтому
- никакая дополнительная входная строка не будет считана в пространство шаблона после того, как в него будет прочитана 1-я строка , если только не будет прочитана последняя , но затем нет дополнительной строки для чтения и неявная
p
команда выполняется.
Таким образом, скрипт в основном читает в 1-й строке ввода и продолжает добавлять следующие строки одну за другой, каждый раз заменяя новую строку пробелом; после добавления последней строки (и \n
изменения в пробеле) N
не может быть добавлена ни одна строка, происходит s
сбой, ta
пропускается , достигается конец сценария, и подразумеваемый p
оператор rint выполняется в текущем однолинейном пространстве шаблона ,
-i
Опция заменяет входной файл file
со всем шаблоном 1 линии.