75

我有一个文件,每行有很多行有很多列(字段)用空白“”分隔每行中的列数不同我想删除前两列如何?

4

9 回答 9

157

你可以这样做cut

cut -d " " -f 3- input_filename > output_filename

解释:

  • cut: 调用 cut 命令
  • -d " ": 使用单个空格作为分隔符(cut默认使用 TAB)
  • -f: 指定要保留的字段
  • 3-:以字段 3 开头的所有字段
  • input_filename: 使用这个文件作为输入
  • > output_filename:将输出写入此文件。

或者,您可以使用awk

awk '{$1=""; $2=""; sub("  ", " "); print}' input_filename > output_filename

解释:

  • awk: 调用 awk 命令
  • $1=""; $2="";: 将字段 1 和 2 设置为空字符串
  • sub(...);:清理输出字段,因为字段 1 和 2 仍将由“”分隔
  • print: 打印修改后的行
  • input_filename > output_filename: 同上。
于 2012-11-19T00:48:21.497 回答
29

这是使用 Awk 的一种相对容易理解的方法:

awk '{print substr($0, index($0, $3))}'

这是一个没有模式的简单 awk 命令,因此{}对每个输入行都运行内部操作。

操作是简单地打印从第三个字段的位置开始的子字符串。

  • $0:整个输入行
  • $3: 第三场
  • index(in, find): 返回find字符串中的位置in
  • substr(string, start):返回从索引开始的子字符串start

如果您想使用不同的分隔符,例如逗号,您可以使用 -F 选项指定它:

awk -F"," '{print substr($0, index($0, $3))}'

您还可以通过在中的操作之前指定模式来对输入行的子集进行操作{}。只有与模式匹配的行才会运行操作。

awk 'pattern{print substr($0, index($0, $3))}'

其中模式可以是:

  • /abcdef/: 使用正则表达式,默认对 $0 进行操作。
  • $1 ~ /abcdef/: 对特定字段进行操作。
  • $1 == blabla: 使用字符串比较
  • NR > 1:使用记录/行号
  • NF > 0:使用字段/列号
于 2013-02-05T19:18:29.030 回答
12

感谢您发布问题。我还想添加对我有帮助的脚本。

awk '{ $1=""; print $0 }' file
于 2014-07-07T01:13:19.633 回答
6

您可以使用sed

sed 's/^[^ ][^ ]* [^ ][^ ]* //'

这会查找以一个或多个非空白、一个空白、另一组一个或多个非空白和另一个空白开头的行,并删除匹配的材料,即前两个字段。[^ ][^ ]*比等效但更明确的符号略短,[^ ]\{1,\}第二个可能会遇到 GNU 的问题sed(尽管如果您将--posix其用作选项,即使 GNUsed也无法搞砸)。OTOH,如果要重复的字符类更复杂,则编号符号会为简洁起见。很容易将其扩展为处理“空白或制表符”作为分隔符,或“多个空白”或“多个空白或制表符”。它也可以修改为在第一个字段之前处理可选的前导空格(或制表符)等。

对于awkcut,请参阅Sampson-Chen回答。还有其他方法可以编写awk脚本,但它们并不比给出的答案更好。请注意,如果您不希望将制表符视为分隔符,则可能需要显式设置字段分隔符 ( -F" ") ,或者字段之间可能有多个空格。awkPOSIX 标准cut不支持字段之间的多个分隔符;GNUcut有一个有用但非标准的-i选项,允许在字段之间使用多个分隔符。

您也可以在纯 shell 中执行此操作:

while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
于 2012-11-19T01:34:41.713 回答
6

只用外壳就可以了

while read A B C; do
echo "$C"
done < oldfile >newfile
于 2014-07-07T02:09:52.167 回答
4

perl:

perl -lane 'print join(' ',@F[2..$#F])' File

awk:

awk '{$1=$2=""}1' File
于 2014-12-10T09:17:46.497 回答
2

使用 awk,并基于下面的一些选项,使用 for 循环会更灵活一些;有时我可能想删除前 9 列(例如,如果我执行“ls -lrt”),所以我将 2 更改为 9,就是这样:

awk '{ for(i=0;i++<2;){$i=""}; print $0 }' your_file.txt

于 2017-12-20T19:13:03.160 回答
1

这可能对您有用(GNU sed):

sed -r 's/^([^ ]+ ){2}//' file

或者对于由一个或多个空格分隔的列:

sed -r 's/^(\S+\s+){2}//' file
于 2012-11-19T07:14:05.560 回答
0

使用脚本

kscript 'lines.split().select(-1,-2).print()' file
于 2017-05-12T08:40:37.447 回答