bernie
bernie

Reputation: 823

swapping characters in 3rd column using sed/awk

A files has 3 columns:

123711184642,3583090366663629,0036f920012437d4 123715942138,3538710295145500,0136f920afd6c643

I want to delete the first two characters in the third column: 123711184642,3583090366663629,36f920012437d4 123715942138,3538710295145500,36f920afd6c643

And swap the first 6 characters, in twos, of the third column such that the final result is: 123711184642,3583090366663629,639f02012437d4 123715942138,3538710295145500,639f02afd6c643

Any assistance will be appreciated. Bernie

Upvotes: 0

Views: 1818

Answers (5)

SiegeX
SiegeX

Reputation: 140417

awk 1-liner just for the fun of it. This doesn't care how many pairs of numbers are in the 3rd field, it will work on all of them.

awk -F, '{$3=substr(gensub(/(.)(.)/,"\2\1","g",$3),3)}1' OFS=, /path/to/file

Input

$ cat ./infile
123711184642,3583090366663629,0036f920012437d4
123715942138,3538710295145500,0136f920afd6c643

Output

$ awk -F, '{$3=substr(gensub(/(.)(.)/,"\\2\\1","g",$3),3)}1' OFS=, ./infile
123711184642,3583090366663629,639f021042734d
123715942138,3538710295145500,639f02fa6d6c34

Upvotes: 0

SiegeX
SiegeX

Reputation: 140417

sed 1-liner. Doesn't care how many fields you have as long as you just want to alter the last. It also doesn't care how many pairs the last field has, it will swap them just the same.

sed 'h;s/^.,..//;s/(.)(.)/\2\1/g;x;s/,[^,]$/,/;G;s/\n//' /path/to/file

Input

$ cat ./infile
123711184642,3583090366663629,0036f920012437d4
123715942138,3538710295145500,0136f920afd6c643

Output

$ sed 'h;s/^.*,..//;s/\(.\)\(.\)/\2\1/g;x;s/,[^,]*$/,/;G;s/\n//' ./infile
123711184642,3583090366663629,639f021042734d
123715942138,3538710295145500,639f02fa6d6c34

Explanation

  1. h -- make a copy of the entire
  2. s/^.*,..// -- Pattern space now holds only the last field with its two leading numbers removed
  3. s/\(.\)\(.\)/\2\1/g -- Do the number swap in pairs on the pattern space
  4. x -- swap pattern space with hold space
  5. s/,[^,]*$/,/ -- Remove the entire last field
  6. G -- Append the hold space to the pattern space with an '\n' between them
  7. s/\n// -- Remove the '\n' added by G

Upvotes: 0

kvista
kvista

Reputation: 5059

Assuming your input data is in the file "foo", you could do:

cat foo | awk -F "," -f awkfile

where awkfile would contain:

{
  v = ""
  p = $3
  printf ("%s,%s,", $1, $2)
  for (i=3; i<9; i=i+2) {
     printf ("%s%s", substr(p, i+1, 1), substr (p, i, 1))
  }
  printf ("%s\n", substr(p, 9))
}

Upvotes: 1

glenn jackman
glenn jackman

Reputation: 247012

With gawk:

gawk -F, '
    BEGIN {OFS=FS}
    { 
        $3 = gensub(/^..(.)(.)(.)(.)(.)(.)(.*)/, "\\2\\1\\4\\3\\6\\5\\7", 1, $3)
        print
    }
' in.txt

Upvotes: 1

marco
marco

Reputation: 4675

With sed it's just a matter of grouping:

sed '
    s/\(.*,\)../\1/;
    s/,\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\([^,]*\)$/,\2\1\4\3\6\5\7/' file

Upvotes: 1

Related Questions