Frage

$ echo "a b" | awk ‚{print $ 0; 1 $ = "1"; print $ 0}‘ a b 1 b

Ich möchte formatiert Ausgabe wie folgt erhalten:

 a       b
 1       b

Gibt es einfache Möglichkeit, das zu tun (ohne IFS, OFS verändert)? Ich bin Spalt in großem Tisch zu ändern und danach sieht es hässlich. Ich möchte nicht, jede Spalte zu formatieren.

Danke.

War es hilfreich?

Lösung

Wahrscheinlich die beste Wahl ist, um die Ausgabe nachbearbeiten. Vielleicht etwas so einfaches wie:

$ ... | awk ... | column -t

funktioniert. (Es sei denn, von „Ich will nicht, jede Spalte zu formatieren“ bedeutet „Ich mag nicht jede Zeile neu zu formatieren“, zB „Ich mag nicht auf Post-Prozess“. In diesem Fall würde ich fragen: „Warum nicht? „)

Andere Tipps

One possible answer (assuming a fixed number of columns):

echo "a       b" | awk '{print $0; $1="1"; printf("%s\t%s\n", $1, $2)}'

Another possible answer (assuming you don't have a good reason to avoid changing the OFS since, you know, that's the whole POINT of having one!):

echo "a       b" | awk 'BEGIN { OFS="\t" } {print $0; $1="1"; print $0}'

This second one has the advantage of working no matter how many columns your text file has.


Edited to add:

To explain why I think your aversion to using the OFS is bizarre, it's just that the whole reason you're getting that formatting change is because of the OFS. The Output Field Separator (OFS) is by default a single space. When you printed $0 the first time, you'd not made any modifications so $0 was the unaltered line. By changing one of the records you made Awk reassess the line by reassembling $0 from the individual fields. Upon reassembling this, of course, Awk inserted the OFS between fields. Because that's what it's supposed to do. Quote from the relevant man page (man gawk):

Assigning a value to an existing field causes the whole record to be rebuilt when $0 is referenced. Similarly, assigning a value to $0 causes the record to be resplit, creating new values for the fields.

Now I agree that there's a bit of an inconsistency between having the first print and the second treat the fields differently, but that's just the way the language is. The OFS isn't inserted until you actually change the string and it actually calculates the fields and rebuilds and so forth.


Further edited to add:

Watch these:

$ awk 'BEGIN { printf("|%s|\n", OFS) }'
| |
$ awk 'BEGIN { OFS="\t" ; printf("|%s|\n", OFS) }'
|   |
$ 

Is the behaviour of Awk in your first example becoming clearer, as well as understanding why you actually need that OFS or a printf or the like?

you can also use substitution

$ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a       b
1       b
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top