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

发布于 2024-10-10 15:07:43 字数 381 浏览 5 评论 0原文

A 文件有 3 列:

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

我想删除第三列中的前两个字符: 123711184642,3583090366663629,36f920012437d4 123715942138,3538710295145500,36f920afd6c643

并交换第三列的前 6 个字符,两两交换,最终结果为: 123711184642,3583090366663629,639f02012437d4 123715942138,3538710295145500,639f02afd6c643

任何帮助将不胜感激。 伯尼

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

山色无中 2024-10-17 15:07:43

假设您的输入数据位于文件“foo”中,您可以这样做:

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

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

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))
}
独木成林 2024-10-17 15:07:43

对于 sed,这只是分组的问题:

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

With sed it's just a matter of grouping:

sed '
    s/\(.*,\)../\1/;
    s/,\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\([^,]*\)$/,\2\1\4\3\6\5\7/' file
所谓喜欢 2024-10-17 15:07:43

与呆呆:

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

With gawk:

gawk -F, '
    BEGIN {OFS=FS}
    { 
        $3 = gensub(/^..(.)(.)(.)(.)(.)(.)(.*)/, "\\2\\1\\4\\3\\6\\5\\7", 1, $3)
        print
    }
' in.txt
回忆躺在深渊里 2024-10-17 15:07:43

sed 1 行。不在乎你有多少个字段,只要你只想改变最后一个字段即可。它也不关心最后一个字段有多少对,它会以相同的方式交换它们。

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

输入

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

输出

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

说明

  1. h -- 复制整个
  2. s/^.* ,..// -- 现在模式空间
    仅保留最后一个字段及其
    删除了两个前导数字
  3. s/\(.\)\(.\)/\2\1/g -- 计算数字
    在模式空间上成对交换
  4. x——用hold交换模式空间
    space
  5. s/,[^,]*$/,/ -- 删除整个
    最后一个字段
  6. G -- 将保留空间附加到
    模式空间之间有 '\n'
    他们
  7. s/\n// -- 删除添加的 '\n'
    G

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
三生一梦 2024-10-17 15:07:43

awk 一行代码只是为了好玩。这并不关心第三个字段中有多少对数字,它适用于所有数字。

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

输入

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

输出

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文