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

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

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

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


当前回答

在这里给出的所有其他答案以及在相关问题中给出的各种可能的FS值都以各种方式失败。有些在开头和/或结尾留下空白,有些将每个FS转换为OFS,有些依赖于仅当FS为默认值时才适用的语义,有些依赖于在括号表达式中否定FS,这将在给定多字符FS时失败,等等。

为了对任何FS都健壮地做到这一点,使用GNU awk的第4个参数split():

$ cat tst.awk
{
    split($0,flds,FS,seps)
    for ( i=n; i<=NF; i++ ) {
        printf "%s%s", flds[i], seps[i]
    }
    print ""
}

$ printf 'a b c d\n' | awk -v n=3 -f tst.awk c d $ printf ' a b c d\n' | awk -v n=3 -f tst.awk c d $ printf ' a b c d\n' | awk -v n=3 -F'[ ]' -f tst.awk b c d $ printf ' a b c d\n' | awk -v n=3 -F'[ ]+' -f tst.awk b c d $ printf 'a###b###c###d\n' | awk -v n=3 -F'###' -f tst.awk c###d $ printf '###a###b###c###d\n' | awk -v n=3 -F'###' -f tst.awk b###c###d Note that I'm using split() above because it's 3rg arg is a field separator, not just a regexp like the 2nd arg to match(). The difference is that field separators have additional semantics to regexps such as skipping leading and/or trailing blanks when the separator is a single blank char - if you wanted to use a while(match()) loop or any form of *sub() to emulate the above then you'd need to write code to implement those semantics whereas split() already implements them for you.

其他回答

awk '{out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}'

我的答案是基于VeeArr的答案,但我注意到它在打印第二列(以及其余部分)之前以空白开始。因为我只有1个声望点,所以我不能评论它,所以这是一个新的答案:

以“out”作为第二列开始,然后添加所有其他列(如果存在)。只要有第二列,这就很好。

我对这里提供的awk解决方案都不满意,因为我想提取前几列,然后打印其余的,所以我转而使用perl。下面的代码提取了前两列,并按原样显示其余部分:

echo -e "a  b  c  d\te\t\tf g" | \
  perl -ne 'my @f = split /\s+/, $_, 3; printf "first: %s second: %s rest: %s", @f;'

与Chris Koknat的perl解决方案相比,优点是实际上只从输入字符串中分离出前n个元素;字符串的其余部分根本没有被分割,因此保持完整。我的示例混合使用空格和制表符来演示这一点。

要更改应该提取的列的数量,请将示例中的3替换为n+1。

这个awk函数返回$0的子字符串,包含从开始到结束的字段:

function fields(begin, end,    b, e, p, i) {
    b = 0; e = 0; p = 0;
    for (i = 1; i <= NF; ++i) {
        if (begin == i) { b = p; }
        p += length($i);
        e = p;
        if (end == i) { break; }
        p += length(FS);
    }
    return substr($0, b + 1, e - b);
}

获取从字段3开始的所有内容:

tail = fields(3);

获取包含字段3到5的$0 section:

middle = fields(3, 5);

函数参数表中的B e p I是一种awk声明局部变量的方式。

您可以使用for循环来循环打印字段$2到$NF(表示行上字段数量的内置变量)。

编辑: 由于"print"附加了换行符,你需要缓冲结果:

awk '{out = ""; for (i = 2; i <= NF; i++) {out = out " " $i}; print out}'

或者,使用printf:

awk '{for (i = 2; i <= NF; i++) {printf "%s ", $i}; printf "\n"}'

如果你想要格式化文本,用echo链接你的命令并使用$0打印最后一个字段。

例子:

for i in {8..11}; do
   s1="$i"
   s2="str$i"
   s3="str with spaces $i"
   echo -n "$s1 $s2" | awk '{printf "|%3d|%6s",$1,$2}'
   echo -en "$s3" | awk '{printf "|%-19s|\n", $0}'
done

打印:

|  8|  str8|str with spaces 8  |
|  9|  str9|str with spaces 9  |
| 10| str10|str with spaces 10 |
| 11| str11|str with spaces 11 |