Ich versuche, Zeilen in einer Datei ohne Änderungen anzuzeigen, aber die anfänglichen Leerzeichen/Tabulatoren werden entfernt, und das lässt sich nicht vermeiden.
Mein Fall: Ich habe eine Ausgabedatei „iptables -L -v“ …
...
Chain INPUT (policy DROP 22641 packets, 2686K bytes)
pkts bytes target prot opt in out source destination
20143 11M ACCEPT all -- * * 0.0.0.0/0
0.0.0.0/0 ctstate RELATED,ESTABLISHED 3648 148K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- ppp0 * 0.0.0.0/0 0.0.0.0/0 ...
und ich versuche, es Zeile für Zeile anzuzeigen ...
...
Chain INPUT (policy DROP 22641 packets, 2686K bytes)
pkts bytes target prot opt in out source destination
20143 11M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
3648 148K DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 ACCEPT all -- tun0 * 0.0.0.0/0 0.0.0.0/0
0 0 ACCEPT all -- ppp0 * 0.0.0.0/0 0.0.0.0/0
...
Anfängliche Leerzeichen werden entfernt (ich weiß nicht, ob Sie das sehen können), wenn ich sie mit diesen Befehlen zeilenweise auflöse:
for L in `cat FILE` | while read L; do echo "$L";done
oder
for L in `cat FILE` | while read L; do printf "%s\n" "$L";done
In diesem Fall zeigt die Ausgabe des Befehls „iptables -L“ linke Spalten rechtsbündig und rechte Spalten linksbündig an, wodurch ein schöner Effekt entsteht. Ich möchte sie Zeile für Zeile anzeigen (ich färbe zum Beispiel einige Zeilen ein), mit identischem Format, aber die Zeilen werden immer linksbündig angezeigt.
Wissen Sie, warum und wie Sie das Problem lösen können?
Antwort1
for L in `cat FILE` | while read L; do echo "$L";done
Ich bezweifle stark, dass Sie das ausführen. Die for
Schleife ist nicht vollständig und Sie sollten einen Syntaxfehler erhalten. Wenn Sie den Befehl in der Befehlsersetzung innerhalb der Wortliste von for
(wie in for L in $(cat foo); do...
) ausführen, werden alle Wörter in separate Zeilen aufgeteilt (und sie dem Dateinamen-Globbing unterzogen).
Allerdings so etwas wie
iptables -vL | while read L; do echo "$L"; done
würde ungefähr die Ausgabe ergeben, die Sie erhalten: read
teilt die Eingabe auf IFS
und zerstört als Nebeneffekt führende und nachfolgende Leerzeichen. Geben Sie ein leeres ein, IFS
um das gewünschte Ergebnis zu erzielen. Außerdem read -r
wird dringend empfohlen, die Verarbeitung von Backslashs zu deaktivieren, auch wenn iptables
die Ausgabe wahrscheinlich keine enthält. Also:
iptables -vL | while IFS= read -r L; do echo "$L"; done
Oder aus einer Datei, ohne cat
:
while IFS= read -r L; do echo "$L"; done < file
Wenn Ihr Ziel darin besteht, die Eingabezeilen irgendwie zu ändern, können Sie hierfür anstelle der Shell auch awk oder Perl verwenden.