【问题标题】:how to remove columns except the last one?如何删除除最后一列之外的列?
【发布时间】:2019-04-26 11:15:08
【问题描述】:

我想移动除最后一列之外的列,我不知道是否有任何方法可以使用 awk 或 sed 或其他一些行命令来做到这一点

 ...
    00000000: 30327c30 30303131 36333132 567c317c  0|2011002136|1|V
    00000010: 44204149 56452045 4d415449 544e4549  IA DE EVITAMIENT
    00000020: 7c007c4f 30327c00 302d3131 37312d33  O|.|.|2011-03-17
    00000030: 3a393020 303a3035 33427c30 38313957   09:50:00|B3W918
    00000040: 327c317c 7c39397c 4f52544f 4f4d7c53  |1|2|99|OTROS|MO
    00000050: 414b4f54 7c007c52 7c007c00 36312d47  TOKAR|.|.|.|G-16
    00000060: 7c54527c 444e4f43 52494355 204e5520  |RT|CONDUCIR UN 
    00000070: 49484556 4f4c5543 524f5020 414e5520  VEHICULO POR UNA
    ...

我试过了,但只删除了第一列

$ cat file | sed -E $'s/ +/\t/g' | cut -f2-

我想要这个结果。最后一栏

    ...
    0|2011002136|1|V
    IA DE EVITAMIENT
    O|.|.|2011-03-17
    09:50:00|B3W918
    |1|2|99|OTROS|MO
    TOKAR|.|.|.|G-16
    |RT|CONDUCIR UN 
    VEHICULO POR UNA
    ...

【问题讨论】:

  • 要保留前面的空格吗?

标签: awk sed


【解决方案1】:

似乎您只是想获取最后 16 个字符。

$ sed 's/.*\(.\{16\}\)/\1/' file
0|2011002136|1|V
IA DE EVITAMIENT
O|.|.|2011-03-17
 09:50:00|B3W918
|1|2|99|OTROS|MO
TOKAR|.|.|.|G-16
|RT|CONDUCIR UN
VEHICULO POR UNA

我仔细查看了您的示例,发现它是使用xxd -e 生成的十六进制转储。如果要获取原始文件,请使用以下内容:

$ xxd -r file | xxd -e | xxd -r > original_file
$ cat original_file
0|2011002136|1|VIA DE EVITAMIENTO|||2011-03-17 09:50:00|B3W918|1|2|99|OTROS|MOTOKAR||||G-16|RT|CONDUCIR UN VEHICULO POR UNA

P.S:original_file 包含 NUL 字节,但它们未显示在终端上。

【讨论】:

    【解决方案2】:

    使用 grep 打印最后 16 个字符的替代方法:

    grep -Po '.{16}$' file

    grep -o '.\{16\}$' file

    • -P 用于 perl 正则表达式
    • -o 仅匹配

    【讨论】:

      【解决方案3】:

      只需删除前 5 个空格分隔的字段。

      使用 GNU sed:

      $ sed -E 's/(\s+\S+){5}\s+//' file
      0|2011002136|1|V
      IA DE EVITAMIENT
      O|.|.|2011-03-17
      09:50:00|B3W918
      |1|2|99|OTROS|MO
      TOKAR|.|.|.|G-16
      |RT|CONDUCIR UN
      VEHICULO POR UNA
      

      使用任何 POSIX sed:

      $ sed 's/\([[:space:]]*[^[:space:]]*\)\{5\}[[:space:]]*//' file
      0|2011002136|1|V
      IA DE EVITAMIENT
      O|.|.|2011-03-17
      09:50:00|B3W918
      |1|2|99|OTROS|MO
      TOKAR|.|.|.|G-16
      |RT|CONDUCIR UN
      VEHICULO POR UNA
      

      【讨论】:

      • 我不认为有任何我喜欢的工具,但如前所述,我确实很欣赏 sed 并且几乎每天都在使用它。在这种情况下,我使用 sed,因为如果示例中的空格是制表符或空格,并且如果它们是空格,我不确定实际数据是否以问题中的空格数开头,那么 cut 对单个字符定界符和 idk 有效,等等。我的直觉是最后两列之间的空格是制表符,而其余的空白,但 idk。使用我发布的 sed 解决方案,我知道无论这些空间是什么,无论它们有多少,它都会起作用,
      【解决方案4】:
      awk '{print "    "$NF}' file
      ...
      0|2011002136|1|V
      EVITAMIENT
      O|.|.|2011-03-17
      09:50:00|B3W918
      |1|2|99|OTROS|MO
      TOKAR|.|.|.|G-16
      UN
      UNA
      ... 
      

      【讨论】:

      • 始终在您的答案中添加解释,以向 OP 和其他人解释您正在解决的问题
      【解决方案5】:

      似乎没有提到最简单的解决方案。

      您真的只想要从第 52 个位置开始的字符。所以使用cut:

      输入:

      ▶ cat > FILE <<EOF
          00000000: 30327c30 30303131 36333132 567c317c  0|2011002136|1|V
          00000010: 44204149 56452045 4d415449 544e4549  IA DE EVITAMIENT
          00000020: 7c007c4f 30327c00 302d3131 37312d33  O|.|.|2011-03-17
          00000030: 3a393020 303a3035 33427c30 38313957   09:50:00|B3W918
          00000040: 327c317c 7c39397c 4f52544f 4f4d7c53  |1|2|99|OTROS|MO
          00000050: 414b4f54 7c007c52 7c007c00 36312d47  TOKAR|.|.|.|G-16
          00000060: 7c54527c 444e4f43 52494355 204e5520  |RT|CONDUCIR UN
          00000070: 49484556 4f4c5543 524f5020 414e5520  VEHICULO POR UNA
      EOF
      

      输出:

      ▶ cut -c52- FILE
      0|2011002136|1|V
      IA DE EVITAMIENT
      O|.|.|2011-03-17
       09:50:00|B3W918
      |1|2|99|OTROS|MO
      TOKAR|.|.|.|G-16
      |RT|CONDUCIR UN
      VEHICULO POR UNA
      

      请注意,可以通过这种方式在 sed 中模拟 cut,如评论中所述:

      ▶ sed -E 's/.{51}//' FILE
      

      另一种方法是使用 AWK 设置字段宽度,如果您有支持它的 AWK 版本,例如 GNU AWK、nawk (Mac OS X) 等。

      ▶ gawk 'BEGIN {FIELDWIDTHS = "15 9 9 9 9 16"} {print $6}' FILE
      0|2011002136|1|V
      IA DE EVITAMIENT
      O|.|.|2011-03-17
       09:50:00|B3W918
      |1|2|99|OTROS|MO
      TOKAR|.|.|.|G-16
      |RT|CONDUCIR UN
      VEHICULO POR UNA
      

      AWK 解决方案的好处是,虽然设置起来需要更多的努力,但它会将更多关于您对数据的期望的信息传达给代码的读者。

      要找出所有列的开始位置,您可以在 Vim 中将光标放在它们上后使用 CTRL + g

      【讨论】:

        【解决方案6】:

        如果您的数据在 d 文件中,请在 gnu awk 上尝试

        awk -F' [a-f0-9]{8}  ' '{print $2}' d
        

        在 gnu sed 上试过

        sed -E 's/.*\s[a-f0-9]{8}\s{2,}(.*)/\1/' d
        

        【讨论】:

          猜你喜欢
          • 2022-07-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-03-17
          • 2020-12-03
          • 2013-08-12
          • 2018-02-01
          相关资源
          最近更新 更多