开发者

swapping characters in 3rd column using sed/awk

开发者 https://www.devze.com 2023-02-02 07:56 出处:网络
A files has 3 columns: 123711184642,3583090366663629,0036f920012437d4 123715942138,3538710295145500,0136f920afd6c643

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


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))
}


With sed it's just a matter of grouping:

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


With gawk:

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


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消