grep -Po '...\K...' 有什么作用?不然怎么能达到这样的效果?

Ord*_*ser 5 linux bash shell

我有这个脚本script.sh

#!/bin/bash
file_path=$1
result=$(grep -Po 'value="\K.*?(?=")' $file_path)
echo $result
Run Code Online (Sandbox Code Playgroud)

和这个文件text.txt

value="a"
value="b"
value="c"
Run Code Online (Sandbox Code Playgroud)

当我运行./script.sh /file/directory/text.txt命令时,终端中的输出如下:

a b c
Run Code Online (Sandbox Code Playgroud)

我明白脚本的作用,但我不明白它是如何工作的,所以我需要对这部分命令进行详细解释:

-Po 'value="\K.*?(?=")'
Run Code Online (Sandbox Code Playgroud)

如果我理解正确的话,\K是一个 Perl 命令。你能在 shell 中给我一个替代方案awk吗(例如用命令)?


先感谢您。

Cha*_*ffy 5

  • grep -P启用 PCRE 语法。(这是一个非标准扩展——甚至不是所有的 GNU grep 版本都支持它,因为它取决于可选的 libpcre 库,并且是否链接它是一个编译时选项)。
  • grep -o在输出中只发出匹配的文本,而不是包含所述文本的整行。(这也是非标准的,虽然比 更广泛可用-P)。
  • \K 是正则表达式语法的 PCRE 扩展,在该点之前丢弃内容,使其不包含在匹配输出中。

由于您的 shell 是 bash,您有内置的 ERE 支持。作为仅使用内置功能的替代方案(没有外部工具grepawk或其他):

#!/usr/bin/env bash
regex='value="([^"]*)"'                    # store regex (w/ match group) in a variable
results=( )                             # define an empty array to store results
while IFS= read -r line; do             # iterate over lines on input
  if [[ $line =~ $regex ]]; then        # ...and, when one matches the regex...
    results+=( "${BASH_REMATCH[1]}" )   # ...put the group's contents in the array
  fi
done <"$1"                              # with stdin coming from the file named in $1
printf '%s\n' "${results[*]}"           # combine array results with spaces and print
Run Code Online (Sandbox Code Playgroud)

http://wiki.bash-hackers.org/syntax/ccmd/conditional_expression为的讨论=~,并http://wiki.bash-hackers.org/syntax/shellvars#bash_rematch对的讨论BASH_REMATCH。有关使用循环逐行读取文件的讨论,请参阅BashFAQ #1while read