什么grep -Po'... \ K ...'做什么?怎么可以实现这种效果?

时间:2017-06-13 14:39:58

标签: linux bash shell

我有这个脚本script.sh

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

和此文件text.txt

value="a"
value="b"
value="c"

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

a b c

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

-Po 'value="\K.*?(?=")'

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

提前谢谢。

1 个答案:

答案 0 :(得分:4)

  • 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

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