这一行一直工作到第二个字段中出现空白。

svn status | grep '\!' | gawk '{print $2;}' > removedProjs

有没有办法让awk打印所有2美元或更大的东西?(3、4美元. .直到我们不再有专栏了?)

我想我应该补充一点,我正在使用Cygwin在Windows环境中执行此操作。


当前回答

使用awk的大多数解决方案都留有空间。这里的选项避免了这个问题。

选项1

一个简单的切割解决方案(只适用于单个分隔符):

command | cut -d' ' -f3-

选项2

强制awk重新计算有时会通过删除第一个字段来删除添加的前导空格(OFS)(适用于某些版本的awk):

command | awk '{ $1=$2="";$0=$0;} NF=NF'

选项3

打印printf格式的每个字段将提供更多的控制:

$ in='    1    2  3     4   5   6 7     8  '
$ echo "$in"|awk -v n=2 '{ for(i=n+1;i<=NF;i++) printf("%s%s",$i,i==NF?RS:OFS);}'
3 4 5 6 7 8

但是,所有之前的答案都将字段之间的所有重复FS更改为OFS。让我们创建一些选项,不做这些。

选项4(推荐)

带有sub的循环删除前面的字段和分隔符。 并且使用FS的值而不是space(可以更改)。 更易于移植,并且不会触发FS到OFS的更改: 注意:^[FS]*是接受前导空格的输入。

$ in='    1    2  3     4   5   6 7     8  '
$ echo "$in" | awk '{ n=2; a="^["FS"]*[^"FS"]+["FS"]+";
  for(i=1;i<=n;i++) sub( a , "" , $0 ) } 1 '
3     4   5   6 7     8

选择5

很有可能构建一个不添加额外(前导或尾随)空白的解决方案,并使用GNU awk中的gensub函数保留现有的空白,如下所示:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          { print(gensub(a""b""c,"",1)); }'
3     4   5   6 7     8 

它也可以用来交换一组给定计数n的字段:

$ echo '    1    2  3     4   5   6 7     8  ' |
  awk -v n=2 'BEGIN{ a="^["FS"]*"; b="([^"FS"]+["FS"]+)"; c="{"n"}"; }
          {
            d=gensub(a""b""c,"",1);
            e=gensub("^(.*)"d,"\\1",1,$0);
            print("|"d"|","!"e"!");
          }'
|3     4   5   6 7     8  | !    1    2  !

当然,在这种情况下,OFS将用于分隔行的两个部分,并且仍然打印字段后面的空白。

注意:[FS]*用于在输入行中允许前导空格。

其他回答

Perl:

@m=`ls -ltr dir | grep ^d | awk '{print \$6,\$7,\$8,\$9}'`;
foreach $i (@m)
{
        print "$i\n";

}

Perl的解决方案:

perl -lane 'splice @F,0,1; print join " ",@F' file

使用这些命令行选项:

-n循环输入文件的每一行,不自动打印每一行 -l在处理之前删除换行符,并在处理之后将它们添加回去 -a autosplit mode -将输入行分割到@F数组中。默认为空格分割 -e执行perl代码

splice @F,0,1从@F数组中清除第0列

join " ",@F连接@F数组的元素,在每个元素之间使用一个空格


Python的解决方案:

[sys.stdout.]写(' ' . join (line.split () [1:]) + ' \ n ')系统的线。Stdin]" <文件

如果你不想重新格式化你没有砍掉的那部分行,我能想到的最好的解决方案写在我的回答中:

如何使用awk打印特定数字后的所有列?

它剪切给定字段号N之前的内容,并打印该行的所有剩余部分,包括字段号N并保持原始间距(它不重新格式化)。如果字段的字符串也出现在行中的其他地方,这并不重要。

定义一个函数:

fromField () { 
awk -v m="\x01" -v N="$1" '{$N=m$N; print substr($0,index($0,m)+1)}'
}

像这样使用它:

$ echo "  bat   bi       iru   lau bost   " | fromField 3
iru   lau bost   
$ echo "  bat   bi       iru   lau bost   " | fromField 2
bi       iru   lau bost 

输出维护所有内容,包括尾随空格

就你的情况而言:

svn status | grep '\!' | fromField 2 > removedProjs

如果你的文件/流在行中间不包含换行字符(你可以使用不同的记录分隔符),你可以使用:

awk -v m="\x0a" -v N="3" '{$N=m$N ;print substr($0, index($0,m)+1)}'

第一种情况只会在包含稀有十六进制字符数字1的文件/流中失败

打印从#2开始的列(输出在开始时没有尾随空格):

ls -l | awk '{sub(/[^ ]+ /, ""); print $0}'
ls -la | awk '{o=$1" "$3; for (i=5; i<=NF; i++) o=o" "$i; print o }'

这个答案还不错,但是自然的间隔消失了。 请将它与这个进行比较:

ls -la | cut -d\  -f4-

然后你就会看到区别了。

甚至ls -la | awk '{$1=$2="";打印},这是基于迄今为止投票选出的最佳答案,即不保留格式。

因此,我将使用以下,它还允许显式选择列在开始:

ls -la | cut -d\  -f1,4-

注意,每个空格也计算列,例如在下面,列1和列3是空的,2是INFO, 4是:

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f1,3

$ echo " INFO  2014-10-11 10:16:19  main " | cut -d\  -f2,4
INFO 2014-10-11
$