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

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

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

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


当前回答

有一个重复的问题,使用cut的答案更简单:

 svn status |  grep '\!' | cut -d\  -f2-

-d指定delimeter(空格),-f指定列列表(所有列都从第2个开始)

其他回答

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 '{print substr($0,length($1)+1);}' < file

它在前面留下了一些空白。

这让我非常恼火,我坐下来写了一个类似cut的字段规范解析器,用GNU Awk 3.1.7测试。

首先,创建一个新的Awk库脚本pfcut。

sudo nano /usr/share/awk/pfcut

然后,粘贴下面的脚本,并保存。之后,是这样的用法:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-4"); }'
t1 t2 t3 t4

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("2-"); }'
t2 t3 t4 t5 t6 t7

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk -f pfcut --source '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

为了避免键入所有这些,我想最好的方法是(参见其他方法)在启动时自动加载用户函数?- Unix & Linux Stack Exchange)为~/.bashrc添加别名;例如:

$ echo "alias awk-pfcut='awk -f pfcut --source'" >> ~/.bashrc
$ source ~/.bashrc     # refresh bash aliases

... 然后你可以调用:

$ echo "t1 t2 t3 t4 t5 t6 t7" | awk-pfcut '/^/ { pfcut("-2,4,6-"); }'
t1 t2 t4 t6 t7

以下是pfcut脚本的源代码:

# pfcut - print fields like cut
#
# sdaau, GNU GPL
# Nov, 2013

function spfcut(formatstring)
{
  # parse format string
  numsplitscomma = split(formatstring, fsa, ",");
  numspecparts = 0;
  split("", parts); # clear/initialize array (for e.g. `tail` piping into `awk`)
  for(i=1;i<=numsplitscomma;i++) {
    commapart=fsa[i];
    numsplitsminus = split(fsa[i], cpa, "-");
    # assume here a range is always just two parts: "a-b"
    # also assume user has already sorted the ranges
    #print numsplitsminus, cpa[1], cpa[2]; # debug
    if(numsplitsminus==2) {
     if ((cpa[1]) == "") cpa[1] = 1;
     if ((cpa[2]) == "") cpa[2] = NF;
     for(j=cpa[1];j<=cpa[2];j++) {
       parts[numspecparts++] = j;
     }
    } else parts[numspecparts++] = commapart;
  }
  n=asort(parts); outs="";
  for(i=1;i<=n;i++) {
    outs = outs sprintf("%s%s", $parts[i], (i==n)?"":OFS); 
    #print(i, parts[i]); # debug
  }
  return outs;
}

function pfcut(formatstring) {
  print spfcut(formatstring);
}

zed_0xff投票最多的答案不适合我。

我有一个日志,其中$5与IP地址可以是更多的文本或没有文本。我需要从IP地址到行尾的所有内容,如果有任何在$5之后。在我的例子中,这实际上是在一个awk程序中,而不是awk一行程序,因此awk必须解决这个问题。当我试图删除前4个字段使用zed_0xff提出的解决方案:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{$1=$2=$3=$4=""; printf "[%s]\n", $0}'

它吐出错误和无用的回应(我添加了[..]以示范):

[    37.244.182.218 one two three]

甚至有人建议将substr与这个错误的答案结合起来,但这只会使事情复杂化。它没有提供任何改进。

相反,如果列的宽度是固定的,直到需要切割点和awk,正确答案是:

echo "  7 27.10.16. Thu 11:57:18 37.244.182.218" | awk '{printf "[%s]\n", substr($0,28)}'

它产生所需的输出:

[37.244.182.218 one two three]

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

如何使用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的文件/流中失败