用awk或sed删除一列

use*_*995 36 awk sed

我有一个包含三列的文件.我想删除第3列(就地编辑).我怎么能用awk或sed做到这一点?

123   abc  22.3
453   abg  56.7
1236  hjg  2.3
Run Code Online (Sandbox Code Playgroud)

期望的输出

123  abc
453  abg
1236 hjg 
Run Code Online (Sandbox Code Playgroud)

Ken*_*ent 59

尝试这个简短的事情:

awk '!($3="")' file
Run Code Online (Sandbox Code Playgroud)

  • 这实际上并没有删除给定的列; 它将它设置为空字符串,但您仍然在输出中获得额外的`FS`.这可能重要,也可能不重要,具体取决于您对转换后的数据所做的工作. (36认同)
  • 这也将重新编译当前记录,用单个空白字符替换字段之间的所有空白区域,并删除任何前导和/或尾随空格.鉴于他的发布输入,它不会产生OP所需的输出.要做到这一点,您需要http://stackoverflow.com/a/38145415/1745001. (3认同)
  • @ A.Danischewski这不是一个好方法,如果awk脚本有错误会怎么样?你丢失了你的文件.拿这个'awk'..'file> tmp && mv tmp file` (2认同)

Ed *_*ton 29

使用GNU awk进行就地编辑\s/\S,以及gensub()删除

1)FIRST字段:

awk -i inplace '{sub(/^\S+\s*/,"")}1' file
Run Code Online (Sandbox Code Playgroud)

要么

awk -i inplace '{$0=gensub(/^\S+\s*/,"",1)}1' file
Run Code Online (Sandbox Code Playgroud)

2)最后一个字段:

awk -i inplace '{sub(/\s*\S+$/,"")}1' file
Run Code Online (Sandbox Code Playgroud)

要么

awk -i inplace '{$0=gensub(/\s*\S+$/,"",1)}1' file
Run Code Online (Sandbox Code Playgroud)

3)N = 3的 N 场:

awk -i inplace '{$0=gensub(/\s*\S+/,"",3)}1' file
Run Code Online (Sandbox Code Playgroud)

没有GNU awk,你需要一个match()+ substr()组合或多个sub()s + vars来删除一个中间字段.另请参阅打印除前三列之外的所有列.

  • 你有这样的规范答案真是太好了:) (2认同)
  • 注意:在Ubuntu Trusty上,GNU Awk 4.0.1默认情况下没有启用`awk` inplace extension. (2认同)

pot*_*ong 17

这可能适合你(GNU sed):

sed -i -r 's/\S+//3' file
Run Code Online (Sandbox Code Playgroud)

如果要删除第3个字段之前的空格:

sed -i -r 's/(\s+)?\S+//3' file
Run Code Online (Sandbox Code Playgroud)

  • @JoshuaCheek`-r`是启用ERE的GNU sed特定选项(谷歌那个).如果使用`-E`而不是`-r`它将在GNU sed和其他一些seds中工作. (3认同)
  • @potong,`\S` 是指_所有不是空格的字符吗?在哪里记录? (2认同)

ton*_*nio 13

看来你可以随便一起去

awk '{print $1 " " $2}' file
Run Code Online (Sandbox Code Playgroud)

这将打印输入文件中每行的两个第一个字段,用空格分隔.

  • 这假设只有3列.否则你需要一个循环:'awk'{printf $ 1 OFS $ 2; for(i = 4; i <= NF; i ++)printf OFS $ i; printf ORS}'file`(OFS默认为空格,ORS默认为换行符). (3认同)

Jon*_*Jon 8

尝试使用 cut... 它快速而简单

首先,您有重复的空格,如果这是您想要的,您可以将它们压缩到列之间的单个空格 tr -s ' '

如果每一列之间已经只有一个分隔符,您可以使用cut -d ' ' -f-2打印字段(列)<= 2。

例如,如果您的数据位于文件 input.txt 中,您可以执行以下操作之一:

cat input.txt | tr -s ' ' | cut -d ' ' -f-2
Run Code Online (Sandbox Code Playgroud)

或者,如果您通过删除第 3 列来更好地解释此问题,您可以编写以下内容

cat input.txt | tr -s ' ' | cut -d ' ' --complement -f3
Run Code Online (Sandbox Code Playgroud)

cut 非常强大,除了列之外,您还可以提取字节或字符的范围

摘自有关如何指定列表范围的语法的手册页

Each LIST is made up of one range, or many ranges separated by commas.
Selected input is written in the same order that it is read, and is
written exactly once. Each range is one of:

  N     N'th byte, character or field, counted from 1
  N-    from N'th byte, character or field, to end of line
  N-M   from N'th to M'th (included) byte, character or field
  -M    from first to M'th (included) byte, character or field
Run Code Online (Sandbox Code Playgroud)

所以你也可以说你想要特定的第 1 列和第 2 列......

cat input.txt | tr -s ' ' | cut -d ' ' -f1,2
Run Code Online (Sandbox Code Playgroud)

  • 我知道这不是问题的答案,但它肯定是最好的答案! (2认同)

Gil*_*not 7

试试这个 :

awk '$3="";1' file.txt > new_file && mv new_file file.txt
Run Code Online (Sandbox Code Playgroud)

要么

awk '{$3="";print}' file.txt > new_file && mv new_file file.txt
Run Code Online (Sandbox Code Playgroud)


小智 7

GNU awk 4.1

awk -i inplace NF--
Run Code Online (Sandbox Code Playgroud)

这将删除每行的最后一个字段.