在匹配给定值的文件中查找正则表达式

时间:2017-01-15 18:18:25

标签: regex linux bash

我对使用grep(bash)的正则表达式有一些基本的了解。 但我想以相反的方式使用正则表达式。

例如,我有一个包含以下条目的文件:

line_one=[0-3]
line_two=[4-6]
line_three=[7-9]

现在我想使用bash来确定特定数字匹配的行。 例如:

grep 8 file

应该返回:

line_three=[7-9]

注意:我知道“grep 8文件”的例子没有意义,但我希望有助于理解我想要实现的目标。

谢谢你的帮助, 烫发

6 个答案:

答案 0 :(得分:3)

正如其他人所指出的那样,awk是正确的工具:

awk -F'=' '8~$2{print $0;}' file

...如果你想让这个工具更像grep,一个快速的bash包装器:

#!/bin/bash
awk -F'=' -v seek_value="$1" 'seek_value~$2{print $0;}' "$2"

哪个会像:

./not_exactly_grep.sh 8 file
line_three=[7-9]

答案 1 :(得分:2)

这可以使用语法[[ $value =~ $regex ]]进行本地bash来测试:

find_regex_matching() {
  local value=$1
  while IFS= read -r line; do         # read from input line-by-line
    [[ $line = *=* ]] || continue     # skip lines not containing an =
    regex=${line#*=}                  # prune everything before the = for the regex
    if [[ $value =~ $regex ]]; then   # test whether we match...
      printf '%s\n' "$line"           # ...and print if we do.
    fi
  done
}

...用作:

find_regex_matching 8 <file

...或者,用你的样本输入内联测试它:

find_regex_matching 8 <<'EOF'
line_one=[0-3]
line_two=[4-6]
line_three=[7-9]
EOF

......适当地发出:

line_three=[7-9]

您可以将printf '%s\n' "$line"替换为printf '%s\n' "${line%%=*}"以仅打印密钥(=之前的内容),如果是这样的话。有关所涉及语法的详细说明,请参阅the bash-hackers page on parameter expansion

答案 2 :(得分:1)

我的第一印象是这不是grep的任务,也许是awk。

尝试用grep做事我只看到这个:

for line in $(cat file); do echo 8 | grep "${line#*=}" && echo "${line%=*}" ; done

使用while进行文件阅读(以下评论):

while IFS= read -r line; do echo 8 | grep "${line#*=}" && echo "${line%=*}" ; done < file

答案 3 :(得分:0)

这不是grep的内置功能,但使用awk很容易,语法有所改变:

/[0-3]/ { print "line one" }
/[4-6]/ { print "line two" }
/[7-9]/ { print "line three" }

如果确实需要,您可以以编程方式将输入文件更改为此语法,如果它不包含任何需要转义的字符(主要是/在正则表达式中或"在字符串中):

sed -e 's@\(.*\)=\(.*\)@/\2/ { print "\1" }@'

答案 4 :(得分:0)

据我了解,您正在寻找包含一些价值的范围。

您可以在gawk

中执行此操作
$ cat /tmp/file
line_one=[0-3]
line_two=[4-6]
line_three=[7-9]

$ awk  -v n=8 'match($0, /([0-9]+)-([0-9]+)/, a){ if (a[1]<n && a[2]>n) print $0 }' /tmp/file
line_three=[7-9]

由于数字被视为数字(与正则表达式相比),因此它支持更大的范围:

$ cat /tmp/file
line_one=[0-3]
line_two=[4-6]
line_three=[75-95]
line_four=[55-105]

$ awk  -v n=92 'match($0, /([0-9]+)-([0-9]+)/, a){ if (a[1]<n && a[2]>n) print $0 }' /tmp/file
line_three=[75-95]
line_four=[55-105]

如果您只是想将=的右侧解释为正则表达式,您可以这样做:

$ awk  -F= -v tgt=8 'tgt~$2' /tmp/file

答案 5 :(得分:0)

你想做点什么

-1 <= m && m <= 0

这将grep你想要的但不会显示在哪里。 使用grep,您可以显示一些消息:

grep -Ef <(cut -d= -f2 file) <(echo 8)

现在您想将regexp文件转换为以下命令:

echo "8" | sed -n '/[7-9]/ s/.*/Found it in line_three/p' 

将这些命令存储在虚拟命令文件中,您将拥有

sed 's#\(.*\)=\(.*\)#/\2/ s/.*/Found at \1/p#' file