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

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

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

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


当前回答

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

其他回答

如果你想要格式化文本,用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 |

这应该是一个相当全面的awk-field子字符串提取函数

根据输入范围返回$0的子字符串,包括 夹入超出范围的值, 处理可变长度字段SEPs 加速治疗::

完全没有输入,直接返回$0 输入值导致有保证的空字符串("") FROM-field == 1 FS = "",将$0按单个字符分割 (因此FROM <(_)>和TO <(__)>字段的行为像cut -c而不是cut -f)

原始$0恢复,w/o覆盖FS seps与OFS

|

 {m,g}awk '{
 2         print "\n|---BEFORE-------------------------\n"
 3         ($0) "\n|----------------------------\n\n  ["
 4         fld2(2, 5) "]\n  [" fld2(3) "]\n  [" fld2(4, 2)
 5         "]<----------------------------------------------should be
 6         empty\n  [" fld2(3, 11) "]<------------------------should be
 7         capped by NF\n  [" fld2() "]\n  [" fld2((OFS=FS="")*($0=$0)+11,
 8         23) "]<-------------------FS=\"\", split by chars
 9         \n\n|---AFTER-------------------------\n" ($0)
10         "\n|----------------------------"
11  }


12  function fld2(_,__,___,____,_____)
13  {
           if (+__==(_=-_<+_ ?+_:_<_) || (___=____="")==__ || !NF) {
              return $_
16         } else if (NF<_ || (__=NF<+__?NF:+__)<(_=+_?_:!_)) {
              return ___
18         } else if (___==FS || _==!___) {
19            return ___<FS \
                 ? substr("",$!_=$!_ substr("",__=$!(NF=__)))__
20               : substr($(_<_),_,__)
21         }
22         _____=$+(____=___="\37\36\35\32\31\30\27\26\25"\
                              "\24\23\21\20\17\16\6\5\4\3\2\1")
23         NF=__
24         if ($(!_)~("["(___)"]")) {
25            gsub("..","\\&&",___) + gsub(".",___,____)
27            ___=____
28         }
29         __=(_) substr("",_+=_^=_<_)

30         while(___!="") {
31            if ($(!_)!~(____=substr(___,--_,++_))) {
32               ___=____
33            break }
35            ___=substr(___,_+_^(!_))
36         }
37         return \
           substr("",($__=___ $__)==(__=substr($!_,
              _+index($!_,___))),_*($!_=_____))(__)
    }'

那些<TAB>是实际的\t \011,但为了显示清晰度重新标记

|---BEFORE------------------------- 
       1   2  33  4444 555555 <TAB>6666666    
|----------------------------

  [2 33 4444 555555]
  [33]
  []<---------------------------------------------- should be empty
  [33 4444 555555 6666666]<------------------------ should be capped by NF
  [       1   2  33  4444 555555 <TAB>6666666    ]
  [ 2  33  4444 555555 <TAB>66]<------------------- FS="", split by chars 

|---AFTER------------------------- 
       1   2  33  4444 555555 <TAB>6666666    
|----------------------------
awk '{out=$2; for(i=3;i<=NF;i++){out=out" "$i}; print out}'

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

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

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
$

如果需要用任意delimeter打印特定列:

awk '{print $3 "  " $4}'

同# 3 # 4

awk '{print $3 "anything" $4}'

与3anythingcol # 4

因此,如果您在一列中有空格,它将是两列,但您可以使用任何分隔符连接它或不使用它。