seahawk1986 schrieb:
[...] read trennt den Text am IFS auf, daher musst du den explizit auf \n
setzen, wenn du Dateien zeilenweise verarbeiten willst - so sollte es z.B. klappen:
| while IFS='\n' read -r line; do echo -e "$line" >> test2; done < test1
|
Das stimmt nicht: read
liest immer bis zum Zeilenende ("One line is read from the standard input" aus der bash Manpage). Und read
liest den kompletten Rest der Zeile in die letzte Variable, deren Namen übergeben wurde ("If there are more words than names, the remaining words and their intervening delimiters are assigned to the last name." ebd). Wenn man wie im ursprünglichen Code nur einen Namen übergibt, landet die gesamte Zeile dort und auch die Anzahl der Leerzeichen innerhalb der Zeile bleibt erhalten.
Man muss auch nicht den Schalter -e bei echo
benutzen, denn der bewirkt lediglich, dass Sequenzen wie "\t", "\n", "\r" u.ä. (zwei Zeichen!) im übergebenen String bei der Ausgabe in Tab, Newline, Carriage Return usw. umgewandelt werden. Damit würde man sogar den ursprünglichen Inhalt verfälschen. Tabs usw., die in der Zeichenkette enthalten sind, werde mit und ohne -e genau so ausgegeben. Zum Vergleich habe ich noch einmal printf
mit genutzt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 | $ printf '\ta\tb\t\nx y\n' >file
$ cat file
a b
x y
$ od -t x1c file
0000000 09 61 09 62 09 0a 78 20 20 20 79 0a
\t a \t b \t \n x y \n
0000014
$ while read line; do echo "$line"; done <file
a b
x y
$ while read line; do printf '%s|\n' "$line"; done <file
a b|
x y|
$ while read line; do echo "$line"; done <file | od -t x1c
0000000 61 09 62 0a 78 20 20 20 79 0a
a \t b \n x y \n
0000012
$ while read line; do printf '%s|\n' "$line"; done <file | od -t x1c
0000000 61 09 62 7c 0a 78 20 20 20 79 7c 0a
a \t b | \n x y | \n
0000014
|
Für das Entfernen von Whitespace am Ende der Zeile ist das Word Splitting verantwortlich ("split into words as described above under Word Splitting" ebd). Und deshalb muss man den IFS auf "leer" setzen.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 | $ while IFS= read line; do echo "$line"; done <file
a b
x y
$ while IFS= read line; do printf '%s|\n' "$line"; done <file
a b |
x y|
$ while IFS= read line; do echo "$line"; done <file | od -t x1c
0000000 09 61 09 62 09 0a 78 20 20 20 79 0a
\t a \t b \t \n x y \n
0000014
$ while IFS= read line; do printf '%s|\n' "$line"; done <file | od -t x1c
0000000 09 61 09 62 09 7c 0a 78 20 20 20 79 7c 0a
\t a \t b \t | \n x y | \n
0000016
|