在Bash中,我想在与awk或grep匹配的模式之后获得字符串的第N个单词



在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中的,还是带有awkgrep?在Bash中,您可以执行以下操作:

while read -ra tokens; do
for idx in "${!tokens[@]}"; do
[[ "${tokens[idx]}" = 'PATTERN' ]] && printf '%sn' "${tokens[idx + 3]}"
done
done

如果PATTERNPRINT_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将使它(甚至(更高效一点。

最新更新