如何使用shell删除文件中的前两列(awk,sed,whatever)

时间:2012-11-19 00:45:53

标签: perl shell awk sed cut

我有一个包含多行的文件 在每一行中有许多列(字段)由空格“”分隔 每行中的列数不同 我想删除前两列 怎么样?

10 个答案:

答案 0 :(得分:134)

您可以使用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&amp; 2仍将由“”
  • 分隔
  • print:打印修改后的行
  • input_filename > output_filename:与上述相同。

答案 1 :(得分:22)

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

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

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

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

  • $0:整个输入行
  • $3:第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:使用字段/列号

答案 2 :(得分:12)

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

awk '{ $1=""; print $0 }' file

答案 3 :(得分:8)

awk '{$1=$2="";$0=$0;$1=$1}1'

输入

a b c d

输出

c d

答案 4 :(得分:6)

您可以使用sed

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

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

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

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

while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file

答案 5 :(得分:6)

它非常直接只用shell来做它

while read A B C; do
echo "$C"
done < oldfile >newfile

答案 6 :(得分:4)

perl的:

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

AWK:

awk '{$1=$2=""}1' File

答案 7 :(得分:1)

这可能适合你(GNU sed):

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

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

sed -r 's/^(\S+\s+){2}//' file

答案 8 :(得分:0)

使用kscript

kscript 'lines.split().select(-1,-2).print()' file

答案 9 :(得分:0)

使用awk,并基于下面的一些选项,使用for循环使得更灵活;有时我可能想要删除前9列(如果我做了#34; ls -lrt&#34;例如),所以我将2更改为9,那就是它:

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