Hi all,
I am a relative novice with awk and am stuck on something I can't help
thinking ought to be really simple. I have a file "mydata.txt" as
below
x 20 x 20 x
x 45 x 45 x
x 100 x 100 x
x 50 x 50 x
I am trying to write a simple script that will output the following
from this file
x 20 x 45 x
x 45 x 20 x
x 100 x 50 x
x 50 x 100 x
I just can't seem to do this, but it must be really simple?
Thanks
Try:
awk 'NR%2{x=$2}!NR%2{$2=x;print;$2=$4;$4=x;print}' mydata.txt
1 Like
awk -F'x' '{a=$2;printf FS $2 FS;getline;printf $3"\n" FS $3 FS a"\n";}' mydata.txt
1 Like
nawk 'BEGIN{ARGV[ARGC++]=ARGV[1]} FNR==NR{a[FNR]=$(NF-1);next}{$(NF-1)=(FNR%2)?a[FNR+1]:a[FNR-1]}1' myFile
1 Like
Thanks vgersh99
Its working, can you tell me which part to change , in case 2 numbers are in different columns ( not 2 and 4)?
Thanks
to swap columns 4 - adjust as needed.
nawk -v c=4 'BEGIN{ARGV[ARGC++]=ARGV[1]} FNR==NR{a[FNR]=$c;next}{$c=(FNR%2)?a[FNR+1]:a[FNR-1]}1' myFile
1 Like
Hi,
In reality my file has thousand of rows and columns.
It would be nice to set explicitly which 2 columns to swap. They can appeare same values in different places, so I should be able to swap values just only on the column positions.
For example in this case:
x 20 x y 20 x
x 45 x y 45 x
x 100 x y 100 x
x 50 x y 50 x
x 70 x y 70 x
x 80 x y 80 x
I want to swap values on column 2 and column5 so I will receive:
x 20 x y 45 x
x 45 x y 20 x
x 100 x y 50 x
x 50 x y 100 x
x 70 x y 80 x
x 80 x y 70 x
Thanks
hernand:
Hi,
In reality my file has thousand of rows and columns.
It would be nice to set explicitly which 2 columns to swap. They can appeare same values in different places, so I should be able to swap values just only on the column positions.
For example in this case:
x 20 x y 20 x
x 45 x y 45 x
x 100 x y 100 x
x 50 x y 50 x
x 70 x y 70 x
x 80 x y 80 x
I want to swap values on column 2 and column5 so I will receive:
x 20 x y 45 x
x 45 x y 20 x
x 100 x y 50 x
x 50 x y 100 x
x 70 x y 80 x
x 80 x y 70 x
Thanks
I don't follow your sample.
Given your latest sample and
nawk -v c=5 'BEGIN{ARGV[ARGC++]=ARGV[1]} FNR==NR{a[FNR]=$c;next}{$c=(FNR%2)?a[FNR+1]:a[FNR-1]}1' yourLatestSample
produces:
x 20 x y 45 x
x 45 x y 20 x
x 100 x y 50 x
x 50 x y 100 x
x 70 x y 80 x
x 80 x y 70 x
anything wrong with that?
1 Like
Hi Vgersh99,
Sorry but your code seems to be working just for my sample file, here is the original file.
I need the spaces between columns, they are important for further parsing.
Thanks
INPUT:
TT0006033250 20110524-07:01:46 GNAGL22 TT GNAGL22
TT0006033250 20110524-07:01:46 BRTPAS44 TT BRTPAS44
XX0000120172 20110524-07:02:08 SORTH21 GG SORTH21
XX0000120172 20110524-07:02:08 TQKUT99 GG TQKUT99
OUTPUT:
TT0006033250 20110524-07:01:46 GNAGL22 TT BRTPAS44
TT0006033250 20110524-07:01:46 BRTPAS44 TT GNAGL22
XX0000120172 20110524-07:02:08 SORTH21 GG TQKUT99
XX0000120172 20110524-07:02:08 TQKUT99 GG SORTH21
---------- Post updated at 07:24 AM ---------- Previous update was at 06:27 AM ----------
Please check, thanks
assuming all the fields are of the constant width....
nawk -v c=5 '
BEGIN {
ARGV[ARGC++]=ARGV[1]
}
FNR==NR && NR==1 {
copy0=$0
for(i=1;i<=NF;i++){
match(copy0, FS FS "*")
fw=RSTART+RLENGTH
copy0=substr(copy0,RSTART+RLENGTH)
}
}
FNR==NR{
a[FNR]=$c
next
}
{
$c=(FNR%2)?a[FNR+1]:a[FNR-1]
for(i=1;i<=NF;i++)
printf("%-*s%c", fw, $i,(i==NF)?ORS:"")
}' yourLatestSample
1 Like
You can also try this:
perl -ane 'if ($.%2){$x=$_;$y=$F[2]};if ($.%2==0) {$x=~s/(([^\s]+\s+){4})\w+/\1$F[4]/;print $x;s/(([^\s]+\s+){4})\w+/\1$y/;print}' mydata.txt
1 Like
Hi Bartus ,
Thanks your code seems to be working.
Just one question where can I set columns , which should swap, because
those could change in different files.
perl -anse 'BEGIN{$c--};if ($.%2){$x=$_;$y=$F[$c]};if ($.%2==0) {$x=~s/(([^\s]+\s+){$c})\w+/\1$F[$c]/;print $x;s/(([^\s]+\s+){$c})\w+/\1$y/;print}' -- -c=5 mydata.txt
c=5 means 5th column.
1 Like
Thanks Bartus
Works perfectly
awk '{
if(NR%2==1)
{
a=sprintf("%s %s %s",$1,$2,$3)
b=sprintf("%s %s %s",$4,$5,$6)
}
else{
print a" "$4" "$5" "$6
print $1" "$2" "$3" "b
}
}' yourfile
1 Like
Hi Bartus,
Your code is working ALMOST correct expect this :
As you can see in case if one of values in 3rd columns is longer/shorter output has last column ('TWT') starting on different position , which is not acceptable for me, all fields should start at the same position.
One solution would be possibility to set column - start position.
Thanks a lot for replies
INPUT:
TT0006033250 20110524-07:01:46 GNAGL22 TT GNAGL22 TWT
TT0006033250 20110524-07:01:46 GNAGL22ZZ TT GNAGL22ZZ TWT
TT0000120172 20110524-07:02:08 SORTH21 GG SORTH21 TWT
TT0000120172 20110524-07:02:08 TQKUT99 GG TQKUT99 TWT
OUTPUT:
TT0006033250 20110524-07:01:46 GNAGL22 TT GNAGL22ZZ TWT
TT0006033250 20110524-07:01:46 GNAGL22ZZ TT GNAGL22 TWT
TT0000120172 20110524-07:02:08 SORTH21 GG TQKUT99 TWT
TT0000120172 20110524-07:02:08 TQKUT99 GG SORTH21 TWT
---------- Post updated at 08:34 AM ---------- Previous update was at 07:05 AM ----------
Hi Bartus,
Please check it , your code is the only one working
Thanks
Try:
perl -nse 'BEGIN{$c--};if ($.%2){$x=$_;/([^\s]+\s+){$c}(\w+\s+)/;$y=$2};if ($.%2==0) {/([^\s]+\s+){$c}(\w+\s+)/;$z=$2;$x=~s/(([^\s]+\s+){$c})\w+\s+/\1$z/;print $x;s/(([^\s]+\s+){$c})\w+\s+/\1$y/;print}' -- -c=5 mydata.txt
PS: I feel bad for anyone supporting this code in the future