在Bash中,我想在与awk匹配的模式之后获得字符串的第N个单词。
示例文本:
hadf asdfi daf PATTERN asdf dsjk PRINT_THIS asdf adas
asdf sdf PATTERN asdf dasdf PRINT_THIS ads asdf PATTERN ads da PRINT_THIS
ads PATTERN ads da PRINT_THIS
例外输出:
PRINT_THIS
PRINT_THIS
PRINT_THIS
PRINT_THIS
因此,如果找到了一个模式,则应该输出匹配后的第二个单词。
我该怎么做?
使用GNU grep:
grep -oP '.*?bPATTERN(?:h+H+){2}h+KS+' file
Perl:
perl -lnE 'while (/.*?bPATTERN(?:h+H+){2}h+(S+)/g) { say $1; }' file
regex 演示和解释
或者带awk:
awk '/PATTERN[[:blank:]]/{for(i=1;i<=NF-3;i++) if ($i ~ /^PATTERN$/) print $(i+3)}' file
所有打印:
PRINT_THIS
PRINT_THIS
PRINT_THIS
PRINT_THIS
那么,它应该是Bash中的,还是带有awk
或grep
的?在Bash中,您可以执行以下操作:
while read -ra tokens; do
for idx in "${!tokens[@]}"; do
[[ "${tokens[idx]}" = 'PATTERN' ]] && printf '%sn' "${tokens[idx + 3]}"
done
done
如果PATTERN
和PRINT_THIS
之间的令牌不能包含另一个PATTERN
,您可以使其更高效(更丑陋(,如下所示:
while read -ra tokens; do
for ((idx = 0; idx < ${#tokens[@]}; ++idx)); do
[[ "${tokens[idx]}" = 'PATTERN' ]] && printf '%sn' "${tokens[idx += 3]}"
done
done
注意+=
而不是+
,如"使循环难以读取101">中所示。
最后但同样重要的是,declare -i idx step
将使它(甚至(更高效一点。