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

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

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

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


当前回答

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

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

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

其他回答

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 -F" " '{ for (i=4; i<=NF; i++) print $i }'

其中-F" "定义了awk使用的分隔符。在我的例子中是空格,它也是awk的默认分隔符。这意味着-F" "可以被忽略。 其中NF定义字段/列的总数。因此,循环将从第4个字段开始,一直到最后一个字段/列。 其中$N检索第N个字段的值。因此,print $i将根据循环计数打印当前字段/列。

Perl:

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

}

这让我非常恼火,我坐下来写了一个类似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);
}
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
$