Wenn ich "cat test.file" verwende, wird es angezeigt
1
2
3
4
Wenn ich die Bash-Datei verwende,
cat test.file |
while read data
do
echo "$data"
done
Wird sich zeigen
1
2
3
4
Wie kann ich das Ergebnis genau wie die ursprüngliche Testdatei erstellen?
{ i=0; while read; do i=$(dc 1 $i + p); printf "%4 d $REPLY\n" $i; done; }
Es ist kompatibel mit alten SH.Antworten:
IFS='' cat test.file | while read data do echo "$data" done
Mir ist klar, dass Sie das Beispiel vielleicht von etwas vereinfacht haben, das wirklich eine Pipeline brauchte, aber bevor es jemand anderes sagt:
IFS='' while read data; do echo "$data" done < test.file
quelle
while IFS= read data; ...
export IFS
..., gut, ich habe dir einen Tipp vorgelesen!IFS= read -r line
, um die Interpretation von Backslashes zu vermeiden.Wenn Sie dem Aufruf "read" kein Argument angeben, setzt read eine Standardvariable namens $ REPLY, die Leerzeichen beibehält. Sie können dies also einfach tun:
$ cat test.file | while read; do echo "$REPLY"; done
quelle
read
.\n
in Ihrer Quelldatei (dh Quellcode)read
in just konvertiert werdenn
. Verwenden Sieread -r
, um dies zu verhindern.$REPLY
Lösung in ZSH nicht funktioniert, dieIFS= read
Lösung jedoch sowohl in ZSH als auch in Bash.Nur um die Antwort von DigitalRoss zu ergänzen.
Für den Fall, dass Sie das IFS nur für diesen Befehl ändern möchten , können Sie geschweifte Klammern verwenden. Wenn Sie dies tun, wird der Wert von IFS nur innerhalb des Blocks geändert. So was:
echo ' word1 word2' | { IFS='' ; while read line ; do echo "$line" check ; done ; }
Die Ausgabe lautet (Leerzeichen behalten):
quelle
IFS
Unset dieses spezielle Beispiel bereits rettet, sollten Sie dennoch zitieren"$line"
. In einem Beispiel aus der realen Welt könnte der Wert immer noch Shell-Platzhalter enthalten und was nicht.IFS='' read -r line
stattdessen! In Ihrem Beispiel läuft die Pipe{..}
in einer Subshell! WieIFS=' '; ( IFS='' ); echo "=$IFS="
welche Drucke= =
(beachten Sie die SPC). Im Gegensatz dazuIFS=' '; { IFS=''; }; echo "=$IFS="
druckt==
(IFS von innen{..}
). Ich würde jedoch eher empfehlen:fullread() { local IFS=''; read -r $1; }
oderIFS='' read -r line
(es gibt kein;' between
IFS = '' `undread
. In ShellsVAR=val cmd args..
ändern Sie die Umgebung für nur einen Befehl (dies funktioniert auch für integrierte Funktionen wieread
).cat -etv <<<"$IFS" ; echo word1 | { IFS=''; cat -etv <<<"$IFS" ; } ; cat -etv <<<"$IFS" ;
. Die Subshell hat das IFS außerhalb des Blocks nicht wie erwartet geändert. Können Sie das näher erläutern?Vielleicht
IFS
ist der entscheidende Punkt, wie andere sagten. Sie müssen nurIFS=
zwischenwhile
und hinzufügenread
.cat test.file | while IFS= read data do echo "$data" done
und vergessen Sie nicht Zitate von
$data
, sonstecho
werden die Leerzeichen gekürzt.Aber wie Joshua Davies erwähnt hat , würden Sie es vorziehen, die vordefinierte Variable zu verwenden
$REPLY
.quelle
read data
teilt die Daten nach IFS auf , was normalerweise "\ t \ n" ist. Dadurch bleiben die Lücken für Sie erhalten:var=$(cat test.file) echo "$var"
quelle
Verwenden Sie alternativ ein gutes Tool zum Parsen von Dateien wie AWK :
awk '{ # Do your stuff print }' file
quelle