Come posso impedire a sed di aggiungere ulteriori caratteri di nuova riga


17

Sto eseguendo i seguenti 2 sedcomandi. Il primo aggiunge i caratteri di nuova riga dove li voglio, il secondo aggiunge anche i caratteri di nuova riga dove li voglio, MA ne aggiunge uno in più alla fine del file dove prima non ce n'era uno.

sed -e 's|\<LIST_G_STATEMENT>|&\
|g' ${XMLDIR}/statement_tmp_1.xml > ${XMLDIR}/statement_tmp_2.xml

sed -e 's|\</LIST_G_STATEMENT>|&\
|g' ${XMLDIR}/statement_tmp_2.xml > ${XMLDIR}/statement_tmp_3.xml

L'utilizzo od -csu tutti e 3 i file fornisce il seguente output.

statement_tmp_1.xml (no \nalla fine del file)

1314700    T   A   T   E   M   E   N   T   >   <   /   L   I   S   T   _
1314720    G   _   S   T   A   T   E   M   E   N   T   >   <   /   G   _
1314740    S   E   T   U   P   >   <   /   L   I   S   T   _   G   _   S
1314760    E   T   U   P   >   <   /   A   R   X   S   G   P   O   >
1314777

statement_tmp_2.xml (no \nalla fine del file)

1314700    S   T   A   T   E   M   E   N   T   >   <   /   L   I   S   T
1314720    _   G   _   S   T   A   T   E   M   E   N   T   >   <   /   G
1314740    _   S   E   T   U   P   >   <   /   L   I   S   T   _   G   _
1314760    S   E   T   U   P   >   <   /   A   R   X   S   G   P   O   >
1315000

statement_tmp_3.xml ( \nalla fine del file - da dove proviene?)

1314700    S   T   A   T   E   M   E   N   T   >   <   /   L   I   S   T
1314720    _   G   _   S   T   A   T   E   M   E   N   T   >  \n   <   /
1314740    G   _   S   E   T   U   P   >   <   /   L   I   S   T   _   G
1314760    _   S   E   T   U   P   >   <   /   A   R   X   S   G   P   O
1315000    >  \n
1315002

Sto eseguendo AIX 5.3

Fondamentalmente, o voglio che smetta di aggiungere il extra \n, o trovare un modo per rimuoverlo.


Solo una domanda: perché stai usando una nuova riga letterale nel tuo modello di sostituzione quando avresti potuto usare s|...|&\n|altrettanto bene?
Joseph R.,

1
@JosephR. \nnella parte destra non è portatile.
Stéphane Chazelas,

@StephaneChazelas È strano. È una cosa CR vs CRLF?
Joseph R.,

2
Un file che non termina con un carattere di nuova riga non è un file di testo, quindi il comportamento con utilità di testo su di essi non è specificato . Utilizzare perlo altri strumenti in grado di gestire dati binari.
Stéphane Chazelas,

4
@JosephR. No, \<LF>è il modo tradizionale e POSIX per aggiungere un carattere LF. \nin genere sostituisce un npersonaggio in qualsiasi cosa tranne GNU sed.
Stéphane Chazelas,

Risposte:


10

Dovresti considerarti fortunato che AIX abbia sedaggiunto i caratteri di nuova riga mancanti.

Un file non vuoto che non termina con un carattere di nuova riga non è un file di testo (almeno secondo la definizione POSIX di un file di testo) poiché un file di testo deve contenere righe e le righe sono un (non troppo lunga) sequenza di caratteri terminata da un carattere di nuova riga, quindi il comportamento delle utilità di testo come sedsu di esso non è specificato e in pratica varia da implementazione a implementazione.

Qualche sedimplementazione avrebbe respinto quel carattere spurio dopo l'ultima riga.

AFAIK, i xmlfile sono pensati per essere file di testo, quindi significa sedche è stato risolto per te.

Se hai bisogno che quel file non finisca con un carattere di nuova riga, allora potresti usare perlo altri strumenti in grado di far fronte a dati non testuali.

perl -pe 's|<LIST_G_STATEMENT>|$&\n|g'

1
La nuova riga di chiusura è utile se si prevede di convogliare l' sedoutput in qualsiasi altra utility Unix standard. Onestamente, non me ne sono accorto sedper anni , dal momento che Bourne shell comanda sostituzioni come $(sed 's/bas/replac/' <<<'basement')tagliare furtivamente la nuova riga finale, se ce n'è una. Ma ci sono momenti in cui sicuramente non lo vuoi; ad esempio , manipolando il testo degli Appunti X con sed. Cordiali saluti, GNU sed, se disponibile, non aggiunge una nuova riga finale se la si utilizza pcon l' -nopzione, come descritto in questa risposta SE .
TheDudeAbides,

0

Ecco un modo per rimuovere la nuova riga finale da un file usando dd:

printf "" | dd  of='/path/to/file' seek=<filesize_in_bytes - 1> bs=1 count=1

Per verificare se un file termina con una nuova riga è possibile utilizzare:

tail -c 1 /path/to/file | tr -dc '\n' | wc -c

E per ottenere la dimensione del file in byte usare:

wc -c < /path/to/file

0

Secondo questa AIX manuale di IBM tailfa -rEverse - che sembra piuttosto fresco. Finché il file è inferiore a 20 KB, dovrebbe funzionare come segue:

tail -r <file | dd bs=1 skip=1 | tail -r >file.new
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.