2010-07-16 13 views
6

Questo è un concetto molto semplice, ma qualcosa che non sono mai stato in grado di articolare così bene. e mi piacerebbe provare a scriverlo e vedere dove sbaglio.Che cos'è il carattere di nuova riga - ' n'

Se necessario, come definirei un "carattere di nuova riga". diciamo che se creo un nuovo file in unix (o windows), il file memorizza le informazioni di "fine riga" inserendo un carattere speciale nel file chiamato "carattere di nuova riga". Se sì, qual è il suo valore ASCII? Ricordo che nei programmi C, ho controllato il carattere letto rispetto al valore '\ n'. E perché questa confusione 2 caratteri per rappresentare caratteri di fine linea ..

bash$ cat states 
California 
Massachusetts 
Arizona 

Say, voglio inserire uno spazio linea di demarcazione tra le linee e si desidera una potenza di forma: output desiderato:

California 

Massachusetts 

Arizona 

bash$sed -e 's/\n/\n\n/g' states does not work. 

Perché non posso trattare "carattere di nuova riga" qui come tratterei qualsiasi altro carattere ed eseguirò qualcosa come il comando precedente. (Capisco che si possa dire che è una questione di sintassi di sed, ma potrebbe spiegare l'intuizione dietro non permettere questo, in modo che io possa liberarmi della mia confusione

Analogamente, all'interno dell'editor di vim, non posso usare:.?% s/\ n/\ n \ n/g Perché così

devo scappare ulteriormente \ n utilizzando una barra rovesciata in sed e dall'interno vim ?.

Grazie ,

Jagrati

+3

* E perché questa confusione 2 caratteri per rappresentare caratteri di fine linea * -. Per il programma, non è in realtà due personaggi - è un personaggio che è "scappato" con una barra inversa. Il compilatore capisce che rappresenta un valore diverso da un normale ASCII ** 'n' **. I caratteri di escape sono comunemente usati in molte lingue e piattaforme per rappresentare caratteri che altrimenti non potresti rappresentare. – GalacticCowboy

+2

Elaborando ciò che ha detto il Cowboy Galattico, '\ n' non è il carattere di nuova riga, è un simbolo che * rappresenta * il carattere di nuova riga nel carattere C e letterali stringa (e in alcuni altri contesti). Il reale carattere di nuova riga nel codice sorgente sarebbe, ovviamente, invisibile, tranne che finirebbe la linea. Questo è il motivo per cui stai riscontrando un problema con sed: '\ n' non rappresenta il carattere di fine riga in quel programma. –

+2

Giuro di aver letto "Che cos'è il carattere di principiante - '\ n'", così stanco – Enriquev

risposta

10

Dal sed man page:

Normalmente, sed ciclicamente copie una linea di ingresso, non compreso il suo carattere terminale di nuova riga, in uno spazio modello, (a meno che non ci sia qualcosa sinistra dopo una funzione "D"), applica tutti i comandi con gli indirizzi che selezionano lo spazio del motivo, copia lo spazio del motivo sullo standard output, aggiungendo una nuova riga ed elimina lo spazio del motivo.

Sta funzionando sulla linea senza il nuovo arrivato, quindi il modello che hai lì non può mai eguagliare. Devi fare qualcos'altro - come la partita contro $ (fine della linea) o ^ (inizio della linea).

Ecco un esempio di qualcosa che ha funzionato per me:

$ cat > states 
California 
Massachusetts 
Arizona 
$ sed -e 's/$/\ 
> /' states 
California 

Massachusetts 

Arizona 

ho digitato un carattere di nuova riga dopo la letterale \ nella linea sed.

+0

'\ n' * fa * funziona in' sed', quindi potresti anche usare solo 'sed 's/$/\ n /' stati' – jabirali

+1

+1 per menzionare gli spazi modello btw :-) – jabirali

+0

@Jabir , non sulla mia macchina. –

11

nuova riga (\ n) è 10 (0xA) e CarriageReturn (\ r) è 13 (0xD).

Diversi sistemi operativi hanno selezionato diverse rappresentazioni di fine riga per i file. Windows utilizza CRLF (\ r \ n). Unix usa LF (\ n). Le versioni precedenti di Mac OS utilizzano CR (\ r), ma OS X è passato al carattere Unix.

Ecco un numero relativamente utile FAQ.

+10

OS 9 usa '\ r'; l'hanno lasciato in OS X e sono passati a corrispondere a Unix –

+4

+1 @Michael, OS X certamente non usa '\ r'. –

+0

Giusto, risolto quello. Sai, puoi anche modificare le risposte. :) –

3
sed 's/$/\n/' states 
+0

In un file codificato con charset us-ascii, ciò non è valido. Devi ottenere il codice ASCII. – ssoto

0

Prova questo:

$ sed -e $'s/\n/\n\n/g' states 
5

caratteri di escape dipendono da qualsiasi sistema li sta interpretando. \n viene interpretato come un carattere di nuova riga da molti linguaggi di programmazione, ma ciò non vale necessariamente per le altre utilità menzionate. Anche se trattano lo \n come newline, potrebbero esserci altre tecniche per indurle a comportarsi come si desidera. Dovresti consultare la loro documentazione (o vedere altre risposte qui).

Per i sistemi DOS/Windows, la nuova riga è in realtà composta da due caratteri: Ritorno a capo (ASCII 13, AKA \r), seguito da Avanzamento riga (ASCII 10). Sui sistemi Unix (incluso Mac OSX) è solo Line Feed. Nei vecchi Mac era un singolo ritorno a capo.

1

Penso che this post di Jeff Attwood risolva perfettamente la tua domanda. Ti porta attraverso le differenze tra le nuove righe su Dos, Mac e Unix e poi spiega la cronologia di CR (ritorno a capo) e LF (avanzamento riga).

+0

Quel post ha il nocciolo fondamentale del problema, ma ha anche alcuni errori fattuali e mezze verità. Potrebbe essere meglio leggere l'argomento newline di Wikipedia. –

1

sed può essere messo in ricerca su più righe & sostituire la modalità per abbinare caratteri di nuova linea \n.

Per fare ciò, sed deve prima leggere l'intero file o stringa nel buffer di attesa ("spazio di attesa") in modo che possa quindi trattare il contenuto di file o stringhe come una singola riga nello "spazio modello".

Per sostituire una singola linea di nuova portabile (rispetto a GNU e FreeBSD sed) è possibile utilizzare una nuova riga "reale" con escape.

# cf. http://austinmatzko.com/2008/04/26/sed-multi-line-search-and-replace/ 
echo 'California 
Massachusetts 
Arizona' | 
sed -n -e ' 
# if the first line copy the pattern to the hold buffer 
1h 
# if not the first line then append the pattern to the hold buffer 
1!H 
# if the last line then ... 
$ { 
# copy from the hold to the pattern buffer 
g 
# double newlines 
s/\n/\ 
\ 
/g 
s/$/\ 
/
p 
}' 

# output 
# California 
# 
# Massachusetts 
# 
# Arizona 
# 

V'è, tuttavia, una molto più conveniente era quello di ottenere lo stesso risultato:

echo 'California 
Massachusetts 
Arizona' | 
    sed G 
0

Vedo un sacco di risposte sed, ma nessuno per vim. Per essere onesti, il trattamento di vim nei personaggi nuovi è un po 'confuso. Cerca \ n ma sostituirlo con \ r. Raccomando RTFM: :help pattern in generale e :help NL-used-for-Nul in particolare.

di fare quello che vuoi con un: comando substitute,

:%s/\_$/\r 

anche se credo che la maggior parte delle persone sarebbe usare qualcosa come

:g/^/put='' 

per lo stesso effetto.

Ecco un modo per trovare la risposta per te. Esegui il tuo file tramite xxd, che fa parte della distribuzione standard di vim.

:%!xxd 

Si ottiene

0000000: 4361 6c69 666f 726e 6961 0a4d 6173 7361 California.Massa 
0000010: 6368 7573 6574 7473 0a41 7269 7a6f 6e61 chusetts.Arizona 
0000020: 0a          . 

Questo dimostra che 46 è il codice esadecimale per C, 61 è il codice per un, e così via.In particolare, 0a (decimale 10) è il codice per \ n. Solo per i calci, provare

:set ff=dos 

prima di filtrare attraverso xxd. Verrà visualizzato 0d0a (CRLF) come terminatore di riga.

:help /\_$ 
:help :g 
:help :put 
:help :! 
:help 23.4 
Problemi correlati