简体   繁体   English

使用sed / awk交换第三列中的字符

[英]swapping characters in 3rd column using sed/awk

A files has 3 columns: 一个文件有3列:

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

I want to delete the first two characters in the third column: 123711184642,3583090366663629,36f920012437d4 123715942138,3538710295145500,36f920afd6c643 我想删除第三列中的前两个字符: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 并交换第三列中的前6个字符(以两位为单位),以使最终结果为:123711184642,3583090366663629,639f02012437d4 123715942138,3538710295145500,639f02afd6c643

Any assistance will be appreciated. 任何帮助将不胜感激。 Bernie 伯尼

Assuming your input data is in the file "foo", you could do: 假设输入数据在文件“ foo”中,则可以执行以下操作:

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

where awkfile would contain: awkfile将包含以下内容:

{
  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只需进行分组即可:

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

With gawk: 使用gawk:

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

sed 1-liner. sed 1班轮。 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/^. sed'h; s / ^。 ,..//;s/(.)(.)/\\2\\1/g;x;s/,[^,] $/,/;G;s/\\n//' /path/to/file ,.. //; s /(。)(。)/ \\ 2 \\ 1 / g; x; s /,[^,] $ /,/; G; s / \\ n //'/ path / to /文件

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 h复制整个
  2. s/^.*,..// -- Pattern space now holds only the last field with its two leading numbers removed s/^.*,..//模式空间现在仅保留最后一个字段,并且删除了两个前导数字
  3. s/\\(.\\)\\(.\\)/\\2\\1/g -- Do the number swap in pairs on the pattern space s/\\(.\\)\\(.\\)/\\2\\1/g在模式空间中成对交换数字
  4. x -- swap pattern space with hold space x用保留空间交换模式空间
  5. s/,[^,]*$/,/ -- Remove the entire last field s/,[^,]*$/,/ -删除整个最后一个字段
  6. G -- Append the hold space to the pattern space with an '\\n' between them G将保留空间添加到模式空间,并在它们之间添加一个'\\ n'
  7. s/\\n// -- Remove the '\\n' added by G s/\\n// -删除由G添加的'\\ n'

awk 1-liner just for the fun of it. awk 1-liner只是为了好玩。 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 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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM