it-swarm.com.de

Was ist ein Zeilenvorschub - '\ n'

Dies ist ein sehr grundlegendes Konzept, aber etwas, das ich noch nie so gut artikulieren konnte. und ich möchte versuchen, es zu buchstabieren und zu sehen, wo ich falsch liege.

Wenn ich muss, wie würde ich ein "Zeilenvorschubzeichen" definieren? Wenn ich beispielsweise eine neue Datei in Unix (oder Windows) erstelle, speichert die Datei die Informationen zum Zeilenende, indem ein Sonderzeichen in die Datei eingefügt wird, das als "neues Zeilenzeichen" bezeichnet wird. Wenn ja, wie hoch ist ihr Wert? Ich erinnere mich daran, dass ich in C-Programmen nach dem Lesezeichen gegen den Wert '\ n' gesucht habe. Und warum dieses verwirrende 2 Zeichen, um Zeilenendezeichen darzustellen ..

bash$ cat states
California
Massachusetts
Arizona

Angenommen, ich möchte einen Zeilenabstand zwischen den Zeilen einfügen und möchte eine Ausgabe der Form: Gewünschte Ausgabe:

California

Massachusetts

Arizona

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

Warum kann ich hier nicht "New Line Character" behandeln, genauso wie ich andere Charaktere behandeln und so etwas wie den obigen Befehl ausführen würde. (Ich verstehe, dass man sagen könnte, dass dies eine Frage der Syntax von sed ist, aber könnte man bitte die Intuition dahinter erklären, dass man das nicht erlaubt, so dass ich meine Verwirrung loswerden kann.

Ebenso kann ich im vim-Editor nicht verwenden:% s/\ n/\ n\n/g. Warum so

Muss ich mit einem Backslash in sed und von vim weiter entkommen ?.

Vielen Dank,

Jagrati

8
xyz

Aus der sed-Manpage :

Normalerweise kopiert sed zyklisch eine Eingabezeile, die das abschließende Zeilenvorschubzeichen nicht enthält, in einen Musterbereich (sofern nicht etwas hinter einer "D" -Funktion übrig ist), werden alle Befehle mit Adressen angewendet, die diesen Musterbereich (Kopien) auswählen den Musterbereich an die Standardausgabe anhängen, einen Zeilenumbruch anhängen und den Musterbereich löschen.

Es arbeitet auf der Linie ohne das Vorhandensein des Zeilenumbruchs, daher kann das Muster, das Sie dort haben, nicht übereinstimmen. Sie müssen etwas anderes tun, beispielsweise einen Vergleich mit $ (Zeilenende) oder ^ (Zeilenanfang).

Hier ist ein Beispiel von etwas, das für mich funktioniert hat:

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

Massachusetts

Arizona

Ich habe nach dem \ in der sed-Zeile ein literales Zeilenvorschubzeichen eingegeben.

10
Carl Norum

NewLine (\ n) ist 10 (0xA) und CarriageReturn (\ r) ist 13 (0xD).

Unterschiedliche Betriebssysteme wählten unterschiedliche Dateien für das Zeilenende aus. Windows verwendet CRLF (\ r\n). Unix verwendet LF (\ n). Ältere Mac OS-Versionen verwenden CR (\ r), aber OS X wurde auf das Unix-Zeichen umgestellt.

Hier ist ein relativ nützliches FAQ .

11
i_am_jorf

Escape-Zeichen sind von dem System abhängig, das sie interpretiert. \n wird von vielen Programmiersprachen als Newline-Zeichen interpretiert. Dies gilt jedoch nicht unbedingt für die anderen von Ihnen erwähnten Dienstprogramme. Selbst wenn sie \n als Zeilenumbruch behandeln, gibt es möglicherweise andere Techniken, um sie dazu zu bringen, sich so zu verhalten, wie Sie möchten. Sie müssten ihre Dokumentation lesen (oder andere Antworten hier sehen).

Bei DOS/Windows-Systemen besteht die Newline eigentlich aus zwei Zeichen: Carriage Return (ASCII 13, AKA \r), gefolgt von Zeilenvorschub (ASCII 10). Auf Unix-Systemen (einschließlich Mac OSX) handelt es sich nur um Zeilenvorschub. Bei älteren Macs war es ein einzelner Wagenrücklauf.

5
Cogwheel
sed 's/$/\n/' states
3
Johan

Ich denke, this post von Jeff Attwood adressiert Ihre Frage perfekt. Es führt Sie durch die Unterschiede zwischen den Zeilenumbrüchen bei Dos, Mac und Unix und erläutert dann die Historie von CR (Carriage Return) und LF (Zeilenvorschub).

1
Corina

sed kann in den mehrzeiligen Such- und Ersetzungsmodus versetzt werden, um den Zeilenvorschubzeichen \n zu entsprechen.

Dazu muss sed zuerst die gesamte Datei oder den gesamten String in den Haltepuffer einlesen ("hold space"), um dann den Inhalt der Datei oder des Strings als eine einzige Zeile in "pattern space" zu behandeln. 

Um eine einzelne Newline portabel (in Bezug auf GNU und FreeBSD sed) zu ersetzen, können Sie eine "echte" Newline-Escape verwenden.

# 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
#

Es ist jedoch viel bequemer, das gleiche Ergebnis zu erzielen:

echo 'California
Massachusetts
Arizona' | 
   sed G
1
cahn

Versuche dies:

$ sed -e $'s/\n/\n\n/g' states
0
Adrian

Ich sehe viele sed Antworten, aber keine für vim. Um fair zu sein, ist Vims Umgang mit Newline-Charakteren etwas verwirrend. Suchen nach \n aber ersetzen mit \r. Ich empfehle RTFM: :help pattern im Allgemeinen und :help NL-used-for-Nul im Besonderen.

Um mit einem: substitute-Befehl zu tun, was Sie wollen,

:%s/\_$/\r

obwohl ich denke, die meisten Leute würden so etwas benutzen

:g/^/put=''

für den gleichen Effekt.

Hier ist eine Möglichkeit, die Antwort für sich selbst zu finden. Führen Sie Ihre Datei über xxd aus, das Teil der Standard-VIM-Distribution ist.

:%!xxd

Du kriegst

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

Dies zeigt, dass 46 der Hex-Code für ist C, 61 ist der Code für a, und so weiter. Insbesondere ist 0a (Dezimal 10) der Code für \n. Probieren Sie es einfach aus

:set ff=dos

vor dem Filtern durch xxd. Sie sehen 0d0a (CRLF) als Zeilenabschluss.

:help /\_$
:help :g
:help :put
:help :!
:help 23.4
0
benjifisher