Perl 如何使用shell(awk、sed等)删除文件中的前两列

Perl 如何使用shell(awk、sed等)删除文件中的前两列,perl,shell,awk,sed,cut,Perl,Shell,Awk,Sed,Cut,我有一个有很多行的文件 在每行中有许多列(字段)由空白“”分隔 每行中的列数不同 我想删除前两列 如何操作?您可以使用cut: cut -d " " -f 3- input_filename > output_filename 说明: cut:调用cut命令 -d”“:使用单个空格作为分隔符(cut默认使用制表符) -f:指定要保留的字段 3-:以字段3开头的所有字段 input\u filename:使用此文件作为输入 >输出\u文件名:将输出写入此文件 或者,您可以使用awk:

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

您可以使用
cut

cut -d " " -f 3- input_filename > output_filename
说明:

  • cut
    :调用cut命令
  • -d”“
    :使用单个空格作为分隔符(
    cut
    默认使用制表符)
  • -f
    :指定要保留的字段
  • 3-
    :以字段3开头的所有字段
  • input\u filename
    :使用此文件作为输入
  • >输出\u文件名
    :将输出写入此文件
或者,您可以使用
awk

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

  • awk
    :调用awk命令
  • $1=”“$2="";:将字段1和2设置为空字符串
  • sub(…):清理输出字段,因为字段1和2仍将由“”分隔
  • 打印
    :打印修改后的行
  • 输入文件名>输出文件名
    :同上

您可以使用
sed

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

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

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

while read junk1 junk2 residue
do echo "$residue"
done < in-file > out-file
读取junk1 junk2残留物时
做回显“$residence”
完成<文件内>文件外
这可能适合您(GNU-sed):

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

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

这里有一种相对容易理解的使用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
    :使用字段/列编号

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

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

      这是相当直接的做它只有外壳

      while read A B C; do
      echo "$C"
      done < oldfile >newfile
      
      在读取A B C时;做
      回音“$C”
      完成newfile
      
      perl:

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

      使用


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


      awk'{for(i=0;i++@wenzi-oops,忘记了
      cut
      默认使用制表符作为分隔符。请参阅更新的答案-刚刚测试过并且有效。在所有其他条件相同的情况下,我建议在
      awk
      上使用
      cut
      。您可以在awk中使用
      awk'{sub(/([^+){2}/,“”)来完成此操作1'
      。我同意,如果您有一个单独的字符字段分隔符,无论如何剪切是更好的选择。仍有一些空白,请使用
      awk'{$1=“”;$2=“”;sub(/^+/,”);print}'
      代替或更短的
      awk'{$1=$2=“”;sub(/^+/,”)}1'
      如果
      残余数
      可以包含反斜杠,则上面的读取将解释它,而不会在输出中再现它。当IFS=read-r…
      时,始终使用
      。如果
      bash
      用普通的
      读取
      解释内容,则
      bash
      将(再次)中断。原始shell中的read命令没有这样的胡说八道;我不相信POSIX shell需要它。如果发现
      bash
      按照您所说的那样做,我会非常恼火-我已经对该程序产生了爱/恨的关系,因为它做了很多事情,但也有一些事情做得不好,比如改变遗留行为是最糟糕的行为之一,需要一个选项来启用旧的标准行为……非常令人恼火。看来你是对的;
      
      
      perl -lane 'print join(' ',@F[2..$#F])' File
      
      awk '{$1=$2=""}1' File
      
      kscript 'lines.split().select(-1,-2).print()' file