grep -i 'search' var/log/sample.log | less -S | awk '{print $1,$2,$3,$31,$32,$33,$34,$35,$36,$37}'
我只想打印从31
到末尾或者从31
到34
元素,而不想一一列出它们。
您能推荐一个for
我可以整合的循环给我吗?
如果您能仅使用 提出解决方案,则可获得加分awk
。
请不要提出建议cut
,因为这不是重点。
谢谢。
答案1
您可以尝试以下方法:
awk '{for (i = 31; i <= NF; i++) printf "%s ",$i;printf "\n"}'
这将打印从 31 到末尾的所有字段如果您想要有特定的限制,请使用如下代码(例如到 34):
awk '{for (i = 31; i <= 34; i++) printf "%s ",$i;printf "\n"}'
答案2
这将打印字段1-3和31-最后一行即可:
awk '
{
for (i=1; i<=3; i++)
printf "%s%s", $i, OFS
for (i=31; i<=NF; i++)
printf "%s%s", $i, OFS
printf "%s", ORS
}'
笔记:
- 我不使用明确的空格来分隔字段,而是使用
OFS
。的默认值OFS
是一个空格。 - 我不使用显式换行符来分隔记录,而是使用
ORS
。的默认值ORS
是换行符。
使用此类标准awk
变量是一种很好的做法。如果您需要非默认值,则无需更改代码(例如awk -v OFS=- …
)。
上面的代码非常简单,但你可能会喜欢也可能不喜欢它关于OFS
s 的“策略”:第一个for
循环总是会生成 3 个OFS
s,即使输入行为空;并且总是会至少有一个尾随OFS
。
以下变体避免了多余的OFS
s:
awk '
{
for (i=1; i<=3 && i<=NF; i++)
printf "%s%s", (i==1)? "" : OFS, $i
for (i=31; i<=NF; i++)
printf "%s%s", OFS, $i
printf "%s", ORS
}'
使用技巧:
i<=NF
第一个循环中的附加条件for
使得它不会打印OFS
输入中不存在的字段。- 我们不是
OFS
在字段之后打印并试图抑制最后一个(尾随)字段,而是OFS
在字段之前打印并抑制第一个打印的字段。重点是很容易分辨出哪个字段将作为输出中的第一个打印(即使可能会有所NF
不同);但很难分辨出哪个字段将作为最后一个打印(如果可能会有所不同NF
)。
另一方面,您的示例代码({print $1,$2,$3,$31,$32,$33,$34,$35,$36,$37}
)打印 10 个字段,并且确切地9秒,即使输入行为空。我不知道这是否是您需要的。打印的最后一个字段后OFS
没有尾随。要实现类似的效果,请尝试以下操作:OFS
awk '
{
for (i=1; i<=3; i++)
printf "%s%s", (i==1)? "" : OFS, $i
for (i=31; i<=NF || i<=37; i++)
printf "%s%s", OFS, $i
printf "%s", ORS
}'
如果输入中有 37 个或更少的字段,则将恰好有 9OFS
个;这将表现得像您的代码。额外的字段(第 38 个及以后)将OFS
在输出中生成更多 s 和字段。
答案3
all-awk(除了确定屏幕宽度,这在 awk 中无法实现)相当于:
grep -i 'search' var/log/sample.log | less -S | awk '{print $1,$2,$3,$31,$32,$33,$34,$35,$36,$37}'
与任何 awk 一起使用:
awk -v width="$(tput cols)" '
{ $0 = substr($0,1,width) }
tolower($0) ~ /search/ {
for (i=1; i<=3; i++) {
printf "%s%s", $i, OFS
}
for (i=31; i<=37; i++) {
printf "%s%s", $i, (i<37 ? OFS : ORS)
}
}
' var/log/sample.log
或者使用 GNU awk 进行 gensub() (未经测试,因为您没有提供任何输入/输出来测试):
awk -v width="$(tput cols)" '
{ $0 = substr($0,1,width) }
tolower($0) ~ /search/ {
print gensub(/\s*((\S+\s+){3})(\S+\s+){27}((\S+\s+){6}\S+).*/,"\\1\\4",1)
}
' var/log/sample.log