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. Але нада. Здається, тут я пропускаю щось дуже важливе / базове.

Відповіді:


16

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

Просто використовуйте tr:

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

Або, ще краще, забудьте sedзовсім:

printf ls | xclip -selection clipboard

Це видалить всі нові рядки, часто не бажані у generate-text | xclipвипадку. Ця відповідь видаляє лише останній новий рядок.
Том Хейл

7

Багато інструментів для обробки тексту, включаючи sed, оперують вмістом рядка, виключаючи символ нового рядка. Перше, що sed робить при обробці рядка, це зняття нового рядка в кінці, потім він виконує команди в сценарії, і він додає остаточний новий рядок під час друку. Таким чином, ви не зможете видалити новий рядок за допомогою sed.

Щоб видалити всі нові рядки, ви можете використовувати trзамість цього:

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


4

Ви можете замінити нові рядки в sed, передавши йому опцію -z .

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

Сторінка чоловіка Sed:

-z, --невільні дані, окремі рядки символами NUL


Це видалить усі нові рядки, що, як правило, не бажано у | xclipвипадку.
Том Хейл

2

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

echo -n "ls " | xclip -selection clipboard

Якщо вам додатково потрібно зробити більш складні перетворення,

echo "ls  " | perl -pe 's/\n//' | xclip -selection clipboard

Хм. Гладкий розчин. Я думаю, що, можливо, саме час перейти на 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 s /.../.../), породжена 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+$//'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.