Come sostituire una parola con una nuova riga


11

Ho un file di testo con i seguenti dati e ogni riga termina con |END|.

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

Sto cercando di sostituire |END|con una \nnuova linea con sed.

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

Ma sta producendo un output errato come di seguito:

 T
 |
 s
 o
 m
 e
 ...

Ma quello che voglio è questo:

T|somthing|something
T|something2|something2

Ho anche provato con tr. Neanche ha funzionato.


Risposte:


15

Usa questo:

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

Quello che hai provato non funziona perché sed usa espressioni regolari di base e l'implementazione di sed ha un \|operatore che significa "o" (un'estensione comune a BRE), quindi ciò che hai scritto sostituisce (stringa vuota o ENDo stringa vuota) con una nuova riga.


È necessario commentare \ in \ n: sed 's / | END | / \\ n / g
Baazigar

@Baazigar No, ciò che AB ha scritto è corretto (almeno per Linux, emetterebbero alcune implementazioni sed \n). La domanda chiede come sostituire |END|con una nuova riga, non con \n.
Gilles 'SO- smetti di essere malvagio' il

I caratteri per newline sono '\ n'. \\ n è necessario perché \ anche è un carattere di escape, quindi se lo fai solo \ n, stai dicendo 'escape this n character'. Quando fai \\ n stai dicendo 'non trattare questo prossimo \ come una via di fuga'.
Baazigar,

7

Quanto segue ha funzionato bene per me:

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

Notare che ho appena inserito una barra rovesciata seguita dal tasto Invio.


2
Questa è la sintassi standard. L'uso \n come nella risposta di @ AB non funzionerebbe con alcune sedimplementazioni.
Stéphane Chazelas,

@ StéphaneChazelas Quale implementazione di sed supporta l' \|alternanza in una regexp ma non \nsignifica newline in una ssostituzione?
Gilles 'SO- smetti di essere malvagio'

5

Puoi usare awk:

$ awk -F'\\|END\\|' '{$1=$1}1' OFS='\n' file
T|somthing|something
T|something2|something2
  • -F'\\|END\\|' imposta il separatore di campo su |END|
  • OFS='\n' imposta il separatore del campo di uscita su newline
  • $1=$1causa awkricostruire $0con OFScome separatore di campo
  • 1è un valore vero, perché awkstampa l'intera riga di input

3

Un altro forse comando e usando la sua RSopzione sarebbe:

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

Stamperà quei record (basati sull'eparatore R ecord S di Awk ) che non sono vuoti (ha almeno un campo) per impedire la stampa di righe vuote.

Testato su questo input:

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

Fornisce questo output:

T|somthing|something
T|something2|something2
Test

Ciò ha cancellato tutte le righe vuote :) Se vuoi avere anche le nuove righe, sostituiscile $1=$1con $0in command:

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

$1=$1condensa sequenze di spazi vuoti in un carattere di spazio e restituisce false se il primo campo è 0. Non ha senso. Probabilmente vuoi awk 1 RS='\\|END\\|'o awk NF RS='\\|END\\|'o awk length RS='\\|END\\|'qui. Nota che un regexp RS richiede gawk o mawk
Stéphane Chazelas

3

Un altro modo con sedquello non stampa le righe vuote:

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

ad es. input:

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

produzione:

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

stessa cosa con ed:

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

1

Come menzionato qui da Walter Mundt , possiamo ottenere questo risultato usando una stringa tra virgolette 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

~ $

Controlla il link qui sopra per altre alternative.

Puoi anche usare la seguente sintassi, non sono sicuro che funzioni su tutti i tipi di 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

~ $

Lavorando su FreeBSD v10. In realtà, l'unico metodo che ha funzionato per me. Grazie.
Sopalajo de Arrierez,

0

Ho avuto lo stesso problema nella rigida shell posix, l'ho fatto in due passaggi con un carattere inutilizzato

cat data.json|tr '§' '?'|sed -e 's/"[^"]":/§&/g'|tr '§' '\n'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.