我编写了以下 awk 脚本:
% echo /var/sysconfig/network/my_functions alpha beta gama | \
awk -v word=alpha '$2 == word { print $0 }'
如何告诉 awk 我想打印除 $1 ( /var/sysconfig/network/my_functions PATH )之外的所有行,这样我将得到以下内容:
alpha beta gama
代替
/var/sysconfig/network/my_functions alpha beta gama
评论:行内容可以是任意内容,不受字符串/单词数量的限制
答案1
我认为在 awk 中除了手动删除第一个字段之外别无他法。(如果您愿意规范字段间空间,还有其他方法。)
awk '$2 == word {match($0, "("FS")+"); print substr($0, RSTART+RLENGTH);}'
答案2
如果设置$1
为,""
您将留下分隔空格。如果您不想这样做,则必须迭代字段:
awk '{for (f=2; f<=NF; ++f) { if (f!=2) {printf("%s",OFS);} printf("%s",$f)}; printf "\n" }'
编辑:根据 Gilles 的评论进行了修复。
做同样事情的另一种方法:
awk '{d = ""; for (f=2; f<=NF; ++f) {printf("%s%s", d, $f); d = OFS}; printf("\n") }'
答案3
不知怎的,我认为使用 cut 命令来做这件事会更容易、更直观:
echo /var/sysconfig/network/my_functions alpha beta gama | cut -d' ' -f 2-
唯一的问题是 cut 不支持同时使用多种不同类型的空格作为分隔符。因此,如果您有空格或制表符,它将无法工作。
答案4
这个(有点复杂的)解决方案有点类似于Gilles 的回答,
- 在行首不输出空格,
- 正确处理输入行以空格开头的情况,并且
- 保留字段间的空格。
awk -v word=alpha '
$2 == word {
i = index($0, $1) # Find $1 within $0 (the line).
if (i > 0) { # Sanity check; should always be true.
i = i + length($1) # Find space after $1.
temp = substr($0, i)
i = index(temp, $2) # Find $2 in remainder of line.
if (i > 0) { # Sanity check; should always be true.
print substr(temp, i)
}
}
}'
我认为在线评论已经解释得很清楚了。我们寻找 $1
在行中的位置(记住,我明确地没有假设它在开头)。然后,Gilles 的回答,我们将$1
(以及它之前的空格,如果有的话)从行中剥离。然后$2
在行的剩余部分中找到 的位置,并剥离其之前的空格。
以下是一些精简内容丹尼斯·威廉姆森的回答。
awk -v word=alpha '$2==word { for (f=2; f<=NF; ++f) printf("%s%s", $f, (f==NF?ORS:OFS)) }'
和 Dennis 的回答一样,它使用默认分隔符输出字段$2
、$3
、...、$NF
(省略$1
)。Dennis 采用了在$3
、...、$NF
(但不采用$2
)之前使用默认输出字段分隔符的方法。我采用了下列的 $2
,,$3
…,$(NF-1)
(但不$NF
)与 OFS 。并且,由于$NF
是接下来是输出记录分隔符(ORS),我们可以使用?:
没有空项的运算符,并消除最后的printf("\n")
。