sed не может удалить символ новой строки

12

Я пользуюсь sedуже довольно давно, но тут есть одна странность, с которой я не могу разобраться.

Позвольте мне объяснить мою проблему с реальным делом.


Сцена 1

printf "ls" | xclip -selection clipboard
echo "ls" | xclip -selection clipboard

В первой команде я printfнаправляю вывод, чтобы xclipон был скопирован в буфер обмена. Теперь в printfотличие от echoне вставляем новую строку в конец по умолчанию. Поэтому, если я вставлю этот контент в терминал, lsскопированная команда не запустится автоматически.

Во втором - новая строка в конце, поэтому вставка содержимого буфера обмена также приводит к выполнению команды в буфере обмена.

Это нежелательно для меня. Итак, я хотел удалить новую строку с помощью sed, но это не удалось, как объяснено в сцене ниже.

Сцена # 2

echo "ls" | sed -r 's/\n//g' | xclip -selection clipboard

Содержимое в буфере обмена по-прежнему содержит новую строку. Когда я вставляю его в терминал, команда запускается автоматически.

Я также попытался удалить символ возврата каретки \r. Но нада. Кажется, я упускаю что-то очень важное / основное здесь.

shivams
источник

Ответы:

16

sed\nразделители на электронных линиях - они всегда удаляются на входе и повторно вставляются на выходе. Там нет и не\n ewline символов в области sedшаблона , которые не происходят в результате редактирования вы сделали. Примечание: за исключением GNU sed«s -zрежим ...

Просто используйте tr:

echo ls | tr -d \\n | xclip -selection clipboard

Или, еще лучше, sedсовсем забыть :

printf ls | xclip -selection clipboard
mikeserv
источник
Это удалит все новые строки, часто нежелательные в этом generate-text | xclipслучае. Этот ответ удаляет только последний перевод строки.
Том Хейл,
7

Многие инструменты обработки текста, включая sed, работают с содержимым строки, за исключением символа новой строки. Первое, что делает sed при обработке строки, это убирает символ новой строки в конце, затем он выполняет команды в сценарии и добавляет заключительный символ новой строки при печати. Таким образом, вы не сможете удалить символ новой строки с помощью sed.

Чтобы удалить все новые строки, вы можете использовать trвместо:

echo "ls" | tr -d '\n' | xclip

Жиль "ТАК - перестань быть злым"
источник
4

Вы можете заменить символы новой строки в sed, передав опцию -z .

sed -z 's/\n/ /g'

Sed man page:

-z, --null-data отдельные строки символами NUL

JSON C11
источник
Это удалит все новые строки, что обычно нежелательно в данном | xclipслучае.
Том Хейл
2

Если вы просто помещаете команды в буфер обмена

echo -n "ls " | xclip -selection clipboard

Если вам дополнительно нужно сделать более сложные преобразования,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard
JJoao
источник
Хм. Гладкое решение. Я полагаю, что пришло время перейти к Perl или Python для регулярных выражений.
Шивамс
3
@shivams - perlи pythonоба гораздо медленнее, чем sedпри правильном использовании. Однако научиться правильно его использовать - вот ключ.
mikeserv
@mikeserv - я согласен; специально для oneliner sed это замечательно. Если преобразования станут более сложными, я предпочитаю perl / python / gawk.
JJoao
1
@JJoa: Ваши предпочтения принадлежат вам самим, но они sedмогут сделать гораздо больше, чем справиться только с однострочниками, и, скорее всего, это будет быстрее, чем у любого другого инструмента, который вы упомянули.
mikeserv
1
@mikeserv - еще раз, я согласен с тобой. Несколько лет назад у меня была система перевода EN-PT, написанная на sed (20000 с /.../.../), сгенерированная sed! И это сработало! Позже он стал Perl, чтобы иметь массивы, хэши, функции, пакеты и CPAN.
JJoao
1

Чтобы удалить только последний символ новой строки , проложите через:

sed -z '$ s/\n$//'

sedне добавит a \0к концу потока, если для разделителя задано значение NULvia -z, тогда как для создания текстового файла POSIX (определяемого как конец a \n) он всегда будет выводить финал \nбез -z.

Например:

$ { echo foo; echo bar; } | sed -z '$ s/\n$//'; echo tender
foo
bartender

И доказать не NULдобавил

$ { echo foo; echo bar; } | sed -z '$ s/\n$//' | xxd
00000000: 666f 6f0a 6261 72                        foo.bar

Чтобы удалить несколько завершающих символов новой строки , проложите через:

sed -Ez '$ s/\n+$//'
Том Хейл
источник