这一行一直工作到第二个字段中出现空白。
svn status | grep '\!' | gawk '{print $2;}' > removedProjs
有没有办法让awk打印所有2美元或更大的东西?(3、4美元. .直到我们不再有专栏了?)
我想我应该补充一点,我正在使用Cygwin在Windows环境中执行此操作。
这一行一直工作到第二个字段中出现空白。
svn status | grep '\!' | gawk '{print $2;}' > removedProjs
有没有办法让awk打印所有2美元或更大的东西?(3、4美元. .直到我们不再有专栏了?)
我想我应该补充一点,我正在使用Cygwin在Windows环境中执行此操作。
当前回答
如果你想要格式化文本,用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函数返回$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声明局部变量的方式。
如果你不想重新格式化你没有砍掉的那部分行,我能想到的最好的解决方案写在我的回答中:
如何使用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的文件/流中失败
我想把建议的答案扩展到字段可能由几个空格分隔的情况——我想这就是OP不使用cut的原因。
我知道OP问了关于awk的问题,但sed方法在这里可以工作(例如从第5列打印到最后一列):
pure sed approach sed -r 's/^\s*(\S+\s+){4}//' somefile Explanation: s/// is the standard command to perform substitution ^\s* matches any consecutive whitespace at the beginning of the line \S+\s+ means a column of data (non-whitespace chars followed by whitespace chars) (){4} means the pattern is repeated 4 times. sed and cut sed -r 's/^\s+//; s/\s+/\t/g' somefile | cut -f5- by just replacing consecutive whitespaces by a single tab; tr and cut: tr can also be used to squeeze consecutive characters with the -s option. tr -s [:blank:] <somefile | cut -d' ' -f5-
您可以使用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"}'