这一行一直工作到第二个字段中出现空白。
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环境中执行此操作。
当前回答
有一个重复的问题,使用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
$