Как заменить слово новой строкой

11

У меня есть текстовый файл со следующими данными, и каждая строка заканчивается |END|.

T|somthing|something|END|T|something2|something2|END|

Я tryig заменить |END|с \nновой строки с СЭД.

 sed 's/\|END\|/\n/g' test.txt

Но он производит неправильный вывод, как показано ниже:

 T
 |
 s
 o
 m
 e
 ...

Но то, что я хочу, это:

T|somthing|something
T|something2|something2

Я тоже пробовал с tr. Это тоже не сработало.

ПАВ
источник

Ответы:

15

Использовать этот:

sed 's/|END|/\n/g' test.txt

То, что вы пытались, не работает, потому что sed использует базовые регулярные выражения , а ваша реализация sed имеет \|оператор, означающий «или» (общее расширение BRE), поэтому то, что вы написали, заменяет (пустую строку ENDили пустую строку) на новую строку.

AB
источник
Нужно закомментировать \ in \ n: sed 's / | END | / \\ n / g
Баазигар
@Baazigar Нет, то, что написал AB, правильно (по крайней мере, для Linux некоторые реализации sed будут генерировать \n). Вопрос в том, как заменить |END|на новую строку, а не на \n.
Жиль "ТАК - перестань быть злым"
Символы для новой строки '\ n'. \\ n необходим, потому что \ также является escape-символом, поэтому, если вы делаете только \ n, вы говорите «экранировать этот n-символ». Когда вы делаете \\ n, вы говорите «не относитесь к этому следующему \ как к побегу».
Баазигар
7

Следующее работало хорошо для меня:

$ sed 's/|END|/\
/g' foobar
T|somthing|something
T|something2|something2

Обратите внимание, что я просто поставил обратную косую черту, а затем клавишу ввода.

unxnut
источник
2
Это стандартный синтаксис. Использование \n ответа «как в @ AB» не будет работать с некоторыми sedреализациями.
Стефан Шазелас
@ StéphaneChazelas Какая реализация sed поддерживает \|чередование в регулярном выражении, но не \nозначает новую строку в sзамене?
Жиль "ТАК - перестань быть злым"
5

Вы можете использовать awk:

$ awk -F'\\|END\\|' '{$1=$1}1' OFS='\n' file
T|somthing|something
T|something2|something2
  • -F'\\|END\\|' установите разделитель полей на |END|
  • OFS='\n' установить разделитель выходного поля на новую строку
  • $1=$1вызвать awkреконструкцию $0с OFSразделителем полей
  • 1является истинным значением, потому что awkпечатать всю строку ввода
cuonglm
источник
3

Другое возможно Команда и использование ее RSопции будет:

awk '$1=$1' RS="\|END\|" file

Напечатает те записи (основанные на разделителе R ecord S awk), которые не являются пустыми (имеет хотя бы одно поле) для предотвращения печати пустых строк.

Проверено на этом входе:

T|somthing|something|END|T|something2|something2|END|
Test|END|
|END|

Дает этот вывод:

T|somthing|something
T|something2|something2
Test

Это очищается все пустые строки :) Если вы хотите , чтобы новые строки тоже заменить $1=$1с $0командует:

awk '$0' RS="\|END\|" file
αғsнιη
источник
$1=$1объединяет последовательности пробелов в один пробел и возвращает false, если первое поле равно 0. Не имеет смысла. Вы, вероятно, хотите awk 1 RS='\\|END\\|'или awk NF RS='\\|END\\|'или awk length RS='\\|END\\|'здесь. Обратите внимание, что регулярное выражение RS требует gawk или mawk
Стефан Шазелас
3

Другой способ sed- не печатать пустые строки:

sed 's/|END|/\
/g;/^$/!P;D' infile

например, вход:

T|one|two|END|T|three|four|END|
T|five|six|END|T|seven|eight|END|
T|nine|ten|END|T|eleven|twelve|END|

вывод:

T|one|two
T|three|four
T|five|six
T|seven|eight
T|nine|ten
T|eleven|twelve

то же самое с ed:

ed -s infile <<'IN'
1,$j
s/|END|/\
/g
,p
q
IN
don_crissti
источник
1

Как уже упоминалось здесь на Walter Мундта , мы можем достичь этого с помощью ANSI C строку в кавычках

sed $'s/|END|/\\\n/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
$'s/|END|/\\\n/g'
T|somthing|something
T|something2|something2

~ $

Проверьте ссылку здесь выше для других альтернатив.

Вы также можете использовать следующий синтаксис, я не уверен, работает ли он на всех разновидностях Unix / Linux

sed 's/|END|/\'$'\n''/g'

~ $ echo 'T|somthing|something|END|T|something2|something2|END|' | sed 
's/|END|/\'$'\n''/g'
T|somthing|something
T|something2|something2

~ $
k_vishwanath
источник
Работаю на FreeBSD v10. На самом деле, единственный метод, который работал для меня. Спасибо вам.
Сопалахо де Арриерес
0

У меня была такая же проблема в строгой оболочке posix, я сделал это в два прохода с неиспользованным символом

cat data.json|tr '§' '?'|sed -e 's/"[^"]":/§&/g'|tr '§' '\n'
Бенамар
источник