ubuntuusers.de

\n und Zeilenumbrüche

Status: Ungelöst | Ubuntu-Version: Xubuntu 20.04 (Focal Fossa)
Antworten |

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

@wxpte: Die Option -e von echo kann auch Escape-Sequenzen ersetzen, aber in dem Beispiel war die überflüssig, weil vorher $'\n' verwendet wurde, in $content also gar keine Escape-Sequenzen mehr vorkamen. Und dort wäre das vielleicht auch gar nicht erwünscht gewesen solche Vorkommen in $line zu ersetzen.

@Umaash: Wie der Inhalt einer Shell-Variablen intern gespeichert wird, geht Dich als Programmierer nichts an. Das ist ein Implementierungsdetail. Bei der Ein- oder Ausgabe von den Daten findet immer eine Umwandlung von der/in die interne Darstellung statt. Und nur diese externe Darstellung kann man beispielsweise mit xxd untersuchen. Üblich ist UTF-8 als externe Darstellung.

Umaash

(Themenstarter)

Anmeldungsdatum:
7. Juni 2016

Beiträge: 123

Danke @wxpte für diesen Befehl.

@Marc_BlackJack_Rintsch

OK. Dann braucht man einen Befehl, der bei der Ausgabe keine Umwandlung macht. Ich vermute mal, dass der Befehl ...

1
xxd -g1 <<< "$var"

... eben genau keine Umwandlung macht. Denn mit Hilfe dieses Befehls sehe ich doch ob in der Variablen $var "\n" (0a) oder "\n" (5c 6e) drin steht. Das heisst dieser Befehl erlaubt es mir tatsächlich herauszufinden, was in dieser Variable drin ist.

Oder habe ich etwas übersehen?

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

Es gibt keinen Weg der keine Umwandlung macht. Das ist nicht vorgesehen. Muss ja auch nicht. Wenn Du wissen willst wie das intern aussieht, schau Dir den Quelltext der Bash an. Aber egal wie es da aussieht, nach aussen hat sie halt ein definiertes Verhalten und das ist was man wissen muss, wenn man Shell-Programme schreibt. Nicht wie das intern gehandhabt wird.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13121

wxpte schrieb:

Marc_BlackJack_Rintsch schrieb:

Wobei da das Dollarzeichen auch noch wichtig ist:

Ist dafür nicht eigentlich die Option -e gedacht?
echo

Ich zögere immer ein wenig, alles mit dem Dollar-Zeichen zu erschlagen, das hat auch so schon zu viele unterschiedliche Bedeutungen: Variablenkenner, Befehlssubstitution und Zeilenende – das sind schon mal drei verschiedene Funktionen, die mir auf Anhieb einfallen. Sicherlich fallen mir bei weiterem Nachdenken noch mehr ein.

Es gibt auch einen Unterschied zwischen $'text' und echo -e 'text': die erste Form produziert einen String-Wert, der Sonderzeichen (Newline, Tab usw.) enthalten kann. Die zweite Form nimmt einen String-Wert, der Sequenzen wie \n enthält, die dann bei der Ausgabe nach Stdout in Sonderzeichen umgewandelt werden. Der Zeitpunkt der Sonderzeichengenerierung ist also unterschiedlich.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$ a='foo\nbar'
$ b=$'foo\nbar'
$ echo "a=$a b=$b"
a=foo\nbar b=foo
bar
$ echo -e "a=$a b=$b"
a=foo
bar b=foo
bar
$ printf 'a=%s b=%s\n' "$a" "$b"
a=foo\nbar b=foo
bar

Umaash

(Themenstarter)

Anmeldungsdatum:
7. Juni 2016

Beiträge: 123

Marc_BlackJack_Rintsch schrieb:

@Umaash: Wie der Inhalt einer Shell-Variablen intern gespeichert wird, geht Dich als Programmierer nichts an. Das ist ein Implementierungsdetail. Bei der Ein- oder Ausgabe von den Daten findet immer eine Umwandlung von der/in die interne Darstellung statt. Und nur diese externe Darstellung kann man beispielsweise mit xxd untersuchen. Üblich ist UTF-8 als externe Darstellung.

Aber wie kann ich jetzt herausfinden, ob in der Variable $block_to_delete auch "EOF" gespeichert wird oder nicht?:

$ block_to_delete=$(cat <<EOF
> whitelist \${HOME}/.zoom
> include whitelist-common.inc
> fdfghghh
> caps.drop all
> EOF
> )

Ich möchte wissen, ob in $block_to_delete die Zeilenumbrüche gespeichert sind und ob die "EOF" gespeichert sind. Ich nehme mal an "EOF" entspricht auch irgend einem ASCI Code.

Der Befehl ...

$ xxd -g1 <<< "$block_to_delete"
00000000: 77 68 69 74 65 6c 69 73 74 20 24 7b 48 4f 4d 45  whitelist ${HOME
00000010: 7d 2f 2e 7a 6f 6f 6d 0a 69 6e 63 6c 75 64 65 20  }/.zoom.include 
00000020: 77 68 69 74 65 6c 69 73 74 2d 63 6f 6d 6d 6f 6e  whitelist-common
00000030: 2e 69 6e 63 0a 66 64 66 67 68 67 68 68 0a 63 61  .inc.fdfghghh.ca
00000040: 70 73 2e 64 72 6f 70 20 61 6c 6c 0a              ps.drop all.

... sagt, es seien keine "EOF"-Zeichen gespeichert. Aber kann ich jetzt der Ausgabe des Befehls xxd trauen? Du sagst ja, es wird immer alles umgearbeitet und nichts wird so angezeigt wie es drin ist. Unterschlägt jetzt vielleicht xxd die "EOF" Zeichen? Oder sind sie wirklich nicht in der Variable?

seahawk1986

Anmeldungsdatum:
27. Oktober 2006

Beiträge: 11233

Wohnort: München

Das EOF ist der Delimiter für das Here-Document (den man nach Gutdünken austauschen kann), das findet seinen Weg nicht in die Variable.

$ read -r -d '' var <<ENDE
> foobar
> spam
> ham
> ENDE 

Wenn man printf statt echo nutzt, kommt man an den unverwursteten String (in dem Fall verhält es sich wie ein echo -n "$var"):

$ printf "%s" "$var" | xxd -g1
00000000: 66 6f 6f 62 61 72 0a 73 70 61 6d 0a 68 61 6d     foobar.spam.ham 

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4658

Wohnort: Berlin

@Umaash: Wie seahawk1986 schon schrieb ist EOF kein Zeichen sondern das ist als Begrenzung des Here-Dokuments, wie die Anführungszeichen Zeichenketten begrenzen. Da sind die Anführungszeichen selbst ja auch nicht Bestandteil der Zeichenkette. Und es muss auch nicht EOF sein, sondern kann eine beliebige Buchstabenkombination sein. Denn es kann ja sein, dass man im Here-Dokument selbst EOF als Text am Zeilenanfang haben möchte. Dann muss man natürlich etwas anderes als Begrenzung verwenden.

Ich weiss das ist hier nur zum testen und ausprobieren, aber bei der Zuweisung an eine Variable ist ein Here-Dokument auch nicht ganz so sinnvoll, denn da könnte man ja einfach(er) eine Zeichenkette zuweisen.

$ block_to_delete='whitelist ${HOME}/.zoom
> include whitelist-common.inc
> fdfghghh
> caps.drop all'
$ echo -n "$block_to_delete" | xxd -g1
00000000: 77 68 69 74 65 6c 69 73 74 20 24 7b 48 4f 4d 45  whitelist ${HOME
00000010: 7d 2f 2e 7a 6f 6f 6d 0a 69 6e 63 6c 75 64 65 20  }/.zoom.include 
00000020: 77 68 69 74 65 6c 69 73 74 2d 63 6f 6d 6d 6f 6e  whitelist-common
00000030: 2e 69 6e 63 0a 66 64 66 67 68 67 68 68 0a 63 61  .inc.fdfghghh.ca
00000040: 70 73 2e 64 72 6f 70 20 61 6c 6c                 ps.drop all
Antworten |