bash 如何在shell程序中grep一个变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1818079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to grep a variable in the shell program?
提问by MaiTiano
#!/bin/bash
for ((var=0; var<20; var++))
do
echo " Number is: $(grep 'Multiple_Frame = echo **$var**' 20mrf.txt | wc -l)" >>statisic.txt
done
This shell program cannot produce correct result which maybe the reason of wrong variable returning in the second grep command.
这个 shell 程序无法产生正确的结果,这可能是第二个 grep 命令中返回错误变量的原因。
How can I grep a variable within the second echo sentence? to grep different things according to the var changing?
如何在第二个 echo 句子中 grep 变量?根据var的变化grep不同的东西?
Many thanks!
非常感谢!
采纳答案by Paused until further notice.
As others have stated, the problem is that the single quotes prevent expansion of the variable. However, using $()
allows you to use double quotes:
正如其他人所说,问题在于单引号会阻止变量的扩展。但是, using$()
允许您使用双引号:
echo " Number is: $(grep "Multiple_Frame = echo **$var**" 20mrf.txt | wc -l)" >>statisic.txt
although I suspect something like this is what you meant:
虽然我怀疑你的意思是这样的:
echo " Number is: $(grep "Multiple_Frame = $var" 20mrf.txt | wc -l)" >>statisic.txt
You should also be aware that grep
has an option to output the countso you can omit wc
:
您还应该知道,grep
有一个输出计数的选项,因此您可以省略wc
:
echo " Number is: $(grep -c "Multiple_Frame = $var" 20mrf.txt)" >>statisic.txt
回答by ghostdog74
@OP, doing what you do that way is rather inefficient. You are calling grep and wc 20 times on the same file. Open the file just once, and get all the things you want in 1 iteration of the file contents. Example in bash 4.0
@OP,这样做效率很低。您在同一个文件上调用了 grep 和 wc 20 次。只需打开文件一次,并在文件内容的 1 次迭代中获得您想要的所有内容。bash 4.0 中的示例
declare -A arr
while read -r line
do
case "$line" in
*"Multiple_Frame ="*)
line=${line#*Multiple_Frame = }
num=${line%% *}
if [ -z ${number_num[$num]} ] ;then
number_num[$num]=1
else
number_num[$num]=$(( number_num[$num]+1 ))
fi
;;
esac
done <"file"
for i in "${!number_num[@]}"
do
echo "Multiple_Frame = $i has ${number_num[$i]} counts"
done
similarly, you can use associative arrays in gawk to help you do this task.
同样,您可以在 gawk 中使用关联数组来帮助您完成此任务。
gawk '/Multiple_Frame =/{
sub(/.*Multiple_Frame = /,"")
sub(/ .*/,"")
arr["Multiple_Frame = "#!/bin/bash
for ((var=0; var < 20; var++))
do
count=`grep "Multiple_Frame = $var" 20mrf.txt | wc -l`
echo " Number is: $count" >> statisic.txt
done
]=arr["Multiple_Frame = "#!/bin/bash
for ((var=0; var<20; var++))
do
echo " Number is: $(grep 'Multiple_Frame = echo **'"$var"'**' 20mrf.txt | wc -l)" >>statisic.txt
done
]+1
}END{
for(i in arr) print i,arr[i]
}' file
回答by NawaMan
You have to store each substitution in a variable. Like this:
您必须将每个替换存储在一个变量中。像这样:
##代码##回答by Craig Trader
Ok, the second [sic] problem is with your quoting on line 5. The reference to $var will never be expanded because it's contained within single quotes. You can fix that by replacing the single quotes ('
) with escaped double quotes (\"
).
好的,第二个 [原文如此] 问题是您在第 5 行的引用。对 $var 的引用永远不会被扩展,因为它包含在单引号中。您可以通过用'
转义双引号 ( \"
)替换单引号 ( )来解决此问题。
The first [sic] problem is that you're trying to do too much in a single line, which causes your nesting problem with quotes. Break the line up into multiple commands, storing intermediary results as necessary. Yeah, it might run a tad slower, but you'll save a LOT of time debugging and maintaining it.
第一个 [原文如此] 问题是您试图在一行中做太多事情,这会导致您的引号嵌套问题。将一行分成多个命令,根据需要存储中间结果。是的,它的运行速度可能会慢一点,但是您可以节省大量调试和维护时间。
Trader's Second Law: If you have to choose between optimizing for performance, and optimizing for maintainability, ALWAYS choose to make your code more maintainable. Computers get faster all the time; Programmers don't.
交易者第二定律:如果您必须在性能优化和可维护性优化之间做出选择,请始终选择使您的代码更易于维护。计算机一直在变快;程序员不会。
回答by Chen Levy
The string inside $(...) is quoted with single quotes ('...'
) this quoting prevents the variable expansion. Use Double quotes instead. In your case:
$(...) 中的字符串用单引号 ( '...'
) 引用,此引用可防止变量扩展。改用双引号。在你的情况下:
Note that in this example, it seems like the double quotes for the echo
command are already opened, but you should note that the $(...)
is evaluated first, and there is no double quotes inside it. So the change here is to close the single quote of the grep
open double quote instead, and close the double quotes and reopen single quote later.
请注意,在此示例中,echo
命令的双引号似乎已经打开,但您应该注意$(...)
首先计算的是,并且其中没有双引号。所以这里的变化是把grep
打开的双引号的单引号改为关闭,稍后关闭双引号再重新打开单引号。
This lengthy explanation illustrates the benefit of breaking the expression apart, as suggested by other answers.
正如其他答案所建议的那样,这个冗长的解释说明了将表达式分开的好处。