0

I have a problem with replacing string.

|Stm=2|Seq=2|Num=2|Svc=101|MsgSize(514)=514|MsgType=556|SymbolIndex=16631

I want to find occurrence of Svc till | appears and swap place with Stm till | appears.

My attempts went to replacing characters and this is not my goal.

sat
  • 14,589
  • 7
  • 46
  • 65

3 Answers3

2
awk -F'|' -v OFS='|' 
      '{a=b=0;
        for(i=1;i<=NF;i++){a=$i~/^Stm=/?i:a;b=$i~/^Svc=/?i:b}
        t=$a;$a=$b;$b=t}7' file

outputs:

|Svc=101|Seq=2|Num=2|Stm=2|MsgSize(514)=514|MsgType=556|SymbolIndex=16631
  • the code exchange the column of Stm.. and Svc.., no matter which one comes first.
Kent
  • 189,393
  • 32
  • 233
  • 301
0

You need to use capture groups and backreferences in a string substition.

The below will swap the 2:

echo '|Stm=2|Seq=2|Num=2|Svc=101|MsgSize(514)=514|MsgType=556|SymbolIndex=16631' | sed 's/\(Stm.*|\)\(.*\)\(Svc.*|\)/\3\2\1/'

As pointed out in the comment from @Kent, this will not work if the strings were not in that order.

c3st7n
  • 1,891
  • 13
  • 15
0

If perl solution is okay, assumes only one column matches each for search terms

$ cat ip.txt 
|Stm=2|Seq=2|Num=2|Svc=101|MsgSize(514)=514|MsgType=556|SymbolIndex=16631

$ perl -F'\|' -lane '
@i = grep { $F[$_] =~ /Svc|Stm/ } 0..$#F;
$t=$F[$i[0]]; $F[$i[0]]=$F[$i[1]]; $F[$i[1]]=$t;
print join "|", @F;
' ip.txt
|Svc=101|Seq=2|Num=2|Stm=2|MsgSize(514)=514|MsgType=556|SymbolIndex=16631
  • -F'\|' -lane split input line on |, see also Perl flags -pe, -pi, -p, -w, -d, -i, -t?
  • @i = grep { $F[$_] =~ /Svc|Stm/ } 0..$#F get index of columns matching Svc and Stm
  • $t=$F[$i[0]]; $F[$i[0]]=$F[$i[1]]; $F[$i[1]]=$t swap the two columns
  • print join "|", @F print the modified array
Sundeep
  • 23,246
  • 2
  • 28
  • 103