# switch values

**URL:** <https://community.unix.com/t/switch-values/288740>\
**Category:** Shell Programming and Scripting\
**Created:** [May 27, 2011, 5:16am UTC](https://community.unix.com/t/switch-values/288740 "2011-05-27T05:16:33Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 5:16am UTC](https://community.unix.com/t/switch-values/288740/1 "2011-05-27T05:16:33Z")

</div>

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

```nohighlight
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

```nohighlight
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

---

<div class="post-metadata">

**Author:** ![bartus11](https://community.unix.com/user_avatar/community.unix.com/bartus11/32/1418_2.png) [@bartus11](https://community.unix.com/u/bartus11)\
**Post date:** [May 27, 2011, 5:25am UTC](https://community.unix.com/t/switch-values/288740/2 "2011-05-27T05:25:52Z")

</div>

Try:

```nohighlight
awk 'NR%2{x=$2}!NR%2{$2=x;print;$2=$4;$4=x;print}' mydata.txt

```

---

<div class="post-metadata">

**Author:** ![pravin27](https://community.unix.com/letter_avatar/pravin27/32/5_5575768a8748004e209b776fc1b2916d.png) [@pravin27](https://community.unix.com/u/pravin27)\
**Post date:** [May 27, 2011, 5:31am UTC](https://community.unix.com/t/switch-values/288740/3 "2011-05-27T05:31:51Z")

</div>

```nohighlight
awk -F'x' '{a=$2;printf FS $2 FS;getline;printf $3"\n" FS $3 FS a"\n";}' mydata.txt

```

---

<div class="post-metadata">

**Author:** ![vgersh99](https://community.unix.com/user_avatar/community.unix.com/vgersh99/32/14851_2.png) [@vgersh99](https://community.unix.com/u/vgersh99)\
**Post date:** [May 27, 2011, 5:33am UTC](https://community.unix.com/t/switch-values/288740/4 "2011-05-27T05:33:01Z")

</div>

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 6:28am UTC](https://community.unix.com/t/switch-values/288740/5 "2011-05-27T06:28:48Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![vgersh99](https://community.unix.com/user_avatar/community.unix.com/vgersh99/32/14851_2.png) [@vgersh99](https://community.unix.com/u/vgersh99)\
**Post date:** [May 27, 2011, 6:34am UTC](https://community.unix.com/t/switch-values/288740/6 "2011-05-27T06:34:32Z")

</div>

to swap columns 4 - adjust as needed.

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 6:50am UTC](https://community.unix.com/t/switch-values/288740/7 "2011-05-27T06:50:35Z")

</div>

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:

```nohighlight
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:

```nohighlight
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

---

<div class="post-metadata">

**Author:** ![vgersh99](https://community.unix.com/user_avatar/community.unix.com/vgersh99/32/14851_2.png) [@vgersh99](https://community.unix.com/u/vgersh99)\
**Post date:** [May 27, 2011, 7:10am UTC](https://community.unix.com/t/switch-values/288740/8 "2011-05-27T07:10:52Z")

</div>

> [@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:
> 
> ```plaintext
> 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:
> 
> ```plaintext
> 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

```plaintext
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:

```plaintext
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?

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 8:24am UTC](https://community.unix.com/t/switch-values/288740/9 "2011-05-27T08:24:55Z")

</div>

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:

```nohighlight
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:

```nohighlight
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

---

<div class="post-metadata">

**Author:** ![vgersh99](https://community.unix.com/user_avatar/community.unix.com/vgersh99/32/14851_2.png) [@vgersh99](https://community.unix.com/u/vgersh99)\
**Post date:** [May 27, 2011, 9:00am UTC](https://community.unix.com/t/switch-values/288740/10 "2011-05-27T09:00:41Z")

</div>

assuming all the fields are of the constant width....

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![bartus11](https://community.unix.com/user_avatar/community.unix.com/bartus11/32/1418_2.png) [@bartus11](https://community.unix.com/u/bartus11)\
**Post date:** [May 27, 2011, 9:02am UTC](https://community.unix.com/t/switch-values/288740/11 "2011-05-27T09:02:00Z")

</div>

You can also try this:

```nohighlight
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

```

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 9:14am UTC](https://community.unix.com/t/switch-values/288740/12 "2011-05-27T09:14:30Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![bartus11](https://community.unix.com/user_avatar/community.unix.com/bartus11/32/1418_2.png) [@bartus11](https://community.unix.com/u/bartus11)\
**Post date:** [May 27, 2011, 9:22am UTC](https://community.unix.com/t/switch-values/288740/13 "2011-05-27T09:22:40Z")

</div>

```nohighlight
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.

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 27, 2011, 9:44am UTC](https://community.unix.com/t/switch-values/288740/14 "2011-05-27T09:44:52Z")

</div>

Thanks Bartus  
Works perfectly

---

<div class="post-metadata">

**Author:** ![summer\_cherry](https://community.unix.com/letter_avatar/summer_cherry/32/5_5575768a8748004e209b776fc1b2916d.png) [@summer\_cherry](https://community.unix.com/u/summer_cherry)\
**Post date:** [May 30, 2011, 6:08am UTC](https://community.unix.com/t/switch-values/288740/15 "2011-05-30T06:08:09Z")

</div>

```nohighlight
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 

```

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 30, 2011, 9:34am UTC](https://community.unix.com/t/switch-values/288740/16 "2011-05-30T09:34:10Z")

</div>

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:

```nohighlight
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:

```nohighlight
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

---

<div class="post-metadata">

**Author:** ![bartus11](https://community.unix.com/user_avatar/community.unix.com/bartus11/32/1418_2.png) [@bartus11](https://community.unix.com/u/bartus11)\
**Post date:** [May 30, 2011, 10:18am UTC](https://community.unix.com/t/switch-values/288740/17 "2011-05-30T10:18:41Z")

</div>

Try:

```nohighlight
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 😛

---

<div class="post-metadata">

**Author:** ![hernand](https://community.unix.com/letter_avatar/hernand/32/5_5575768a8748004e209b776fc1b2916d.png) [@hernand](https://community.unix.com/u/hernand)\
**Post date:** [May 30, 2011, 11:20am UTC](https://community.unix.com/t/switch-values/288740/18 "2011-05-30T11:20:46Z")

</div>

Thanks Barturs
