Reputation: 52820
This question is related to using awk to print every second field but I am having problems to print it neatly
$ cat printEachSecondColumnValue
1,11,111,1111,11111
2,22,222,2222,22222
3,33,333,3333,33333
4,44,444,4444,44444
5,55,555,5555,55555
6,66,666,6666,66666
$ gawk -v RS=, -v ORS="\n" '0==NR%2' printEachSecondColumnValue
11
1111
22
2222
33
3333
44
4444
55
5555
66
6666
$ gawk -v RS=, -v ORS="," '0==NR%2' printEachSecondColumnValue
11,1111,22,2222,33,3333,44,4444,55,5555,66,6666,
while I want to get
11,1111
22,2222
33,3333
44,4444
55,5555
66,6666
Can you explain the behaviour of the command piece-by-piece and how to define the inline-separator and EOF differently to get the two columns?
Upvotes: 0
Views: 129
Reputation: 58510
while I want to get
11,1111 22,2222 33,3333 44,4444 55,5555 66,6666
Pardon this intrusion of the obvious, but that's just
awk 'BEGIN { FS = OFS = ","} { print $2, $4 }'
for the given data.
To print the even fields regardless of how many there are, we can replace the print
with a loop:
awk 'BEGIN {
FS = OFS = ","
}
{
for (i = 2; i <= NF; i += 2) {
printf "%s", i
if (i + 2 <= NF)
printf OFS
}
printf "\n"
}'
Alternative logic for the commas:
for (i = 2; i <= NF; i += 2) {
if (i > 2)
printf OFS
printf "%s", i
}
Now, for something a little different. What if we edit the fields to the set we want? Then we can just print them with print
!
awk 'BEGIN { FS = OFS = ","}
{
for (i = 2; i <= NF; i += 2) {
j = i/2
$j = $i
}
NF = j
print
}'
When we assign to NF
, it means there are now that many fields.
If we change any of the fields, or change NF
, then the value of $0
which print
prints by default is re-calculated by combining the field values with OFS
between them.
Smarter Awk, implemented as a Lisp macro in the TXR Language:
$ txr -e '(awk (:set fs "," ofs fs)
(t (set f (select f (range 1 : 2)))
(prn)))'
1,2,3,4,5,6,7,8,9,10
2,4,6,8,10
1,2,3,4
2,4
Here the (:set ...)
clause is for setting up initial variables; fs
is the analog of FS
and set to the comma; ofs
is set to fs
.
The t
means Boolean true: this clause fires for every record. We then edit the list of fields f
by selecting the second, third, fourth, which are indicated by the zero-based list (1 3 5 7 9 ...)
. We generate an infinite, lazy version of this index list using (range 1 : 2)
and feed it to the select
function.
Assigning to f
causes the record variable rec
(analogous to $0
) to be re-constituted with ofs
. The prn
function with no arguments prints rec
.
We can get rid of that modification of f
and side effect of setting rec
by feeding the output of select
directly as arguments to prn
with apply
:
txr -e '(awk (:set fs "," ofs fs)
(t [apply prn (select f (range 1 : 2))])))'
"Apply prn
to the even fields, with ofs
being the comma."
Upvotes: 2