我对使用grep(bash)的正则表达式有一些基本的了解。 但我想以相反的方式使用正则表达式。
例如,我有一个包含以下条目的文件:
line_one=[0-3]
line_two=[4-6]
line_three=[7-9]
现在我想使用bash来确定特定数字匹配的行。 例如:
grep 8 file
应该返回:
line_three=[7-9]
注意:我知道“grep 8文件”的例子没有意义,但我希望有助于理解我想要实现的目标。
谢谢你的帮助, 烫发
答案 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