sed non riesce a rimuovere il carattere di nuova riga


12

Sto usando sedda un po 'di tempo ma ecco una stranezza con cui sono venuto in mente, che non sono in grado di risolvere.

Lasciami spiegare il mio problema con il caso reale.


Scena 1

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

Nel primo comando, installo l' printfoutput in xclipmodo che venga copiato negli Appunti. Ora, printfdiversamente da echonon inserire una nuova riga alla fine per impostazione predefinita. Quindi, se incollo questo contenuto nel terminale, il lscomando che viene copiato non viene eseguito automaticamente.

Nel secondo, c'è una nuova riga alla fine, quindi incollare il contenuto degli appunti comporta anche l'esecuzione del comando negli appunti.

Questo non è desiderabile per me. Quindi, volevo rimuovere la nuova riga usando sed, ma non è riuscita, come spiegato nella scena qui sotto.

Scene # 2

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

Il contenuto negli Appunti contiene ancora new-line. Quando lo incollo nel terminale, il comando viene eseguito automaticamente.

Ho anche provato a rimuovere il carattere di ritorno a capo \r. Ma nada. Sembra che mi manchi qualcosa di molto cruciale / di base qui.

Risposte:


16

seddelimitazioni su \newline: vengono sempre rimosse sull'input e reinserite sull'output. Non c'è mai un \ncarattere di ewline in uno sedspazio modello che non si è verificato a seguito di una modifica effettuata. Nota: con l'eccezione di GNU sed's -zmodalità ...

Usa solo tr:

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

O, meglio ancora, dimentica del sedtutto:

printf ls | xclip -selection clipboard

Ciò rimuoverà tutte le nuove righe, spesso non desiderabili nel generate-text | xclipcaso. Questa risposta rimuove solo l'ultima riga.
Tom Hale,

7

Molti strumenti di elaborazione del testo, incluso sed, operano sul contenuto della riga, escludendo il carattere di nuova riga. La prima cosa che sed fa durante l'elaborazione di una linea è di eliminare la nuova riga alla fine, quindi esegue i comandi nello script e aggiunge una nuova riga finale quando si stampa. Quindi non sarai in grado di rimuovere la nuova riga con sed.

Per rimuovere tutte le newline, puoi usare trinvece:

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


4

È possibile sostituire le nuove righe in sed passando l' opzione -z .

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

Pagina man di Sed:

-z, --null-data separa le righe in base ai caratteri NUL


Ciò rimuoverà tutte le nuove righe, cosa generalmente non desiderata nel | xclipcaso.
Tom Hale,

2

Se stai semplicemente inserendo i comandi negli appunti

echo -n "ls " | xclip -selection clipboard

Se è inoltre necessario apportare trasformazioni più complesse,

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

Hmm. Soluzione liscia. Immagino sia forse il momento di passare a perl o python per regex.
Shivams,

3
@shivams - perle pythonsono entrambi molto più lenti di sedquando possono essere usati correttamente. Imparare a usarlo correttamente è la chiave, però.
Mikeserv,

@mikeserv - Sono d'accordo; speciale per oneliner sed è meraviglioso. Se le trasformazioni diventeranno più complesse, allora preferisco perl / python / gawk.
JJoao,

1
@JJoa: la tua preferenza è la tua, ma sedpuò fare molto di più che gestire solo i tuoi one-liner, e probabilmente può farlo più velocemente di qualsiasi altro degli altri strumenti che menzioni.
Mikeserv,

1
@mikeserv - ancora una volta, sono d'accordo con te. Qualche anno fa avevo un sistema di traduzione EN-PT scritto in sed (20000 s /.../.../), generato da sed! E ha funzionato! Successivamente divenne Perl, per avere array, hash, funzioni, pacchetti e CPAN.
JJoao,

1

Per rimuovere solo l'ultima riga , passare attraverso:

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

sednon aggiungerà a \0alla fine dello stream se il delimitatore è impostato su NULvia -z, mentre per creare un file di testo POSIX (definito per terminare in a \n), produrrà sempre un finale \nsenza -z.

Per esempio:

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

E per dimostrare di non aver NULaggiunto:

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

Per rimuovere più newline finali , passare attraverso:

sed -Ez '$ s/\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.