Como substituir uma palavra por nova linha

11

Eu tenho um arquivo de texto com os seguintes dados e cada linha termina com |END|.

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

Estou tentando substituir |END|com \nnova linha com sed.

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

Mas está produzindo resultados errados, como abaixo:

 T
 |
 s
 o
 m
 e
 ...

Mas o que eu quero é isso:

T|somthing|something
T|something2|something2

Eu também tentei com tr. Também não funcionou.

Sas
fonte

Respostas:

15

Usa isto:

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

O que você tentou não funciona porque o sed usa expressões regulares básicas e sua implementação sed possui um \|operador que significa “ou” (uma extensão comum ao BRE); portanto, o que você escreveu substitui (string ENDvazia ou string vazia) por uma nova linha.

AB
fonte
Precisa comentar o \ in \ n: sed 's / | END | / \\ n / g
Baazigar
@ Baazigar Não, o que a AB escreveu está correto (pelo menos para Linux, algumas implementações sed seriam emitidas \n). A pergunta pergunta como substituir |END|por uma nova linha, não por \n.
Gilles 'SO- stop be evil'
Os caracteres da nova linha são '\ n'. O \\ n é necessário porque \ também é um caractere de escape; portanto, se você fizer apenas \ n, estará dizendo 'escape this n character'. Quando você faz \ \ n, você está dizendo 'não trate isso a seguir \ como uma fuga'.
precisa saber é o seguinte
7

O seguinte funcionou bem para mim:

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

Observe que eu apenas coloquei uma barra invertida seguida pela tecla Enter.

desnatado
fonte
2
Essa é a sintaxe padrão. Usar \n como na resposta da @ AB não funcionaria com algumas sedimplementações.
Stéphane Chazelas
@ StéphaneChazelas Que implementação sed suporta \|alternância em uma regexp, mas não \nsignifica nova linha em uma ssubstituição?
Gilles 'SO- stop be evil'
5

Você pode usar awk:

$ awk -F'\\|END\\|' '{$1=$1}1' OFS='\n' file
T|somthing|something
T|something2|something2
  • -F'\\|END\\|' defina o separador de campos para |END|
  • OFS='\n' definir separador de campo de saída como nova linha
  • $1=$1causar awkreconstruir $0com OFScomo separador de campo
  • 1é um valor verdadeiro, porque awkimprime toda a linha de entrada
cuonglm
fonte
3

Outro possivelmente comando e usando sua RSopção seria:

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

Imprimirá os registros (com base no do awk R ecord S eparator), que não estão vazias (tem pelo menos um campo) para evitar a impressão de linhas vazias.

Testado nesta entrada:

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

Dá esta saída:

T|somthing|something
T|something2|something2
Test

Isso limpou todas as linhas vazias :) Se você quiser ter novas linhas também, substitua $1=$1por $0no comando:

awk '$0' RS="\|END\|" file
αғsнιη
fonte
$1=$1condensa seqüências de espaços em branco em um caractere de espaço e retorna false se o primeiro campo for 0. Não faz sentido. Você provavelmente quer awk 1 RS='\\|END\\|'ou awk NF RS='\\|END\\|'ou awk length RS='\\|END\\|'aqui. Note-se que um regexp RS requer gawk ou mawk
Stéphane Chazelas
3

Outra maneira com sedisso não imprime linhas vazias:

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

por exemplo, entrada:

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

resultado:

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

mesma coisa com ed:

ed -s infile <<'IN'
1,$j
s/|END|/\
/g
,p
q
IN
don_crissti
fonte
1

Como mencionado aqui por Walter Mundt , podemos conseguir isso usando uma string citada 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

~ $

Confira o link acima aqui para outras alternativas.

Você também pode usar a seguinte sintaxe, não tenho certeza se funciona em todos os tipos de 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
fonte
Trabalhando no FreeBSD v10. Na verdade, único método que funcionou para mim. Te agradece.
Sopalajo de Arrierez
0

Eu tive um mesmo problema no shell estrito posix eu fiz isso em duas passagens com um char não utilizado

cat data.json|tr '§' '?'|sed -e 's/"[^"]":/§&/g'|tr '§' '\n'
Benamar
fonte