簡體   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