繁体   English   中英

grep输出在bash脚本中有所不同

[英]grep output different in bash script

我正在创建一个bash脚本,该脚本将仅使用grep来查看一堆日志中的某个字符串。

有趣的事情发生了。

为了测试所有日志文件,文件被命名为test1.log,test2.log,test3.log等。

使用grep命令时:

grep -oHnR TEST Logs/test*

输出包含预期的文件夹中所有文件的所有实例。

但是当使用命令但包含在下面的bash脚本中时:

#!/bin/bash
#start

grep -oHnR $1 $2

#end

输出仅显示1个文件中的实例。

运行脚本时,我使用以下命令:

bash test.bash TEST Logs/test*

这是预期输出的示例(仅使用grep时会发生的情况):

Logs/test2.log:8:TEST    
Logs/test2.log:20:TEST    
Logs/test2.log:41:TEST    
Logs/test.log:2:TEST    
Logs/test.log:18:TEST

这是使用bash脚本时收到的输出示例:

Logs/test2.log:8:TEST    
Logs/test2.log:20:TEST    
Logs/test2.log:41:TEST

有人可以向我解释为什么会这样吗?

拨打电话时

bash test.bash TEST Logs/test*

这将由外壳程序翻译为

bash test.bash TEST Logs/test1.log Logs/test2.log Logs/test3.log Logs/test4.log

(如果您有四个日志文件)。

命令行参数TESTLogs/test1.logLogs/test2.log等将被赋予名称$1$2$3等。 $1将是TEST$2将是Logs/test1.log

仅使用$2时,您只需忽略其余参数,仅使用一个日志文件。

正确的版本是这样的:

#!/bin/bash
#start

grep -oHnR "$@"

#end

这样可以正确地传递所有参数,还可以处理文件名中的空格之类的麻烦事情(您的版本可能会遇到麻烦)。

要了解发生了什么,可以使用一个更简单的脚本:

#!/bin/bash
echo $1
echo $2

根据您的要求,输出前两个参数。

您要使用第一个参数,然后将其余所有参数用作输入文件。 因此,使用shift这样:

#!/bin/bash
search=$1
shift

echo "$1"
echo "$@"

还请注意使用双引号。

在您的情况下,因为您希望将搜索字符串和文件名以相同的顺序传递到grep ,所以您甚至不需要shift

#!/bin/bash

grep -oHnR -e "$@"

(我添加了-e以防搜索字符串以-开头)

未加引号*受着通配符 ,当你调用脚本。

使用set -x输出脚本中正在运行的内容可以使这一点更加清楚。

$ ./greptest.sh TEST test*
++ grep -oHnR TEST test1.log
$ ./greptest.sh TEST "test*"
++ grep -oHnR TEST test1.log test2.log test3.log

在第一种情况下,bash将*扩展到文件名列表,而第二种情况是将bash传递给grep。 在第一种情况下,您实际上有> 2个args(因为扩展的每个文件名都将成为arg)-在脚本中添加echo $#也会显示以下内容:

$ ./greptest.sh TEST test*
++ grep -oHnR TEST test1.log
++ echo 4
4
$ ./greptest.sh TEST "test*"
++ grep -oHnR TEST test1.log test2.log test3.log
++ echo 2
2

您可能想在bash调用中转义通配符:

bash test.bash TEST Logs/test\*

这样,它将以*传递给grep,否则shell会将其扩展到Logs目录中名称以test开头的每个文件。

或者,更改脚本以在命令行上允许多个文件:

#!/bin/bash
hold=$1
shift
grep -oHnR $hold $@

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM