2013-01-19 22 views
4

我正在努力傳遞包含在變量中的幾個grep模式。這是我的代碼:使用變量在bash中傳遞grep模式

#!/bin/bash 
GREP="$(which grep)" 
GREP_MY_OPTIONS="-c" 
for i in {-2..2} 
do 
    GREP_MY_OPTIONS+=" -e "$(date --date="$i day" +'%Y-%m-%d') 
done 
echo $GREP_MY_OPTIONS 

IFS=$'\n' 
MYARRAY=($(${GREP} ${GREP_MY_OPTIONS} "/home/user/this path has spaces in it/"*"/abc.xyz" | ${GREP} -v :0$)) 

這就是我想要它做的事:

  • 確定/界定其中的grep是
  • 分配控股參數,我將傳遞給一個變量(GREP_MY_OPTIONS) grep的
  • 分配多個圖案GREP_MY_OPTIONS
  • 使用grep和我都存儲在$ GREP_MY_OPTIONS模式搜索包含空格的路徑中的幾個文件,並把它們在ARR唉

當我使用「回聲$ GREP_MY_OPTIONS」這也帶來我所期待的,但是當我運行該腳本,它失敗的錯誤:

/斌/ grep的:無效選項 - 「」

我在做什麼錯?如果路徑中沒有空格,那麼一切似乎都可以正常工作,所以我認爲這與IFS有關,但我不確定。

+0

你會介意做:'echo「$ {GREP} $ {GREP_MY_OPTIONS} \」/ home/user /此路徑中有空格/ \「* \」/ abc.xyz \「| $ {GREP} -v:0 $「',看看將要執行的實際命令是什麼? – Rubens

+0

This produced: /bin/grep -c -e 2013-01-17 -e 2013-01-18 -e 2013-01-19 -e 2013-01-20 -e 2013-01-21 -e 2013 -01-22 -e 2013-01-23 -e 2013-01-24 -e 2013-01-25「/ home/user /此路徑中有空格/」*「/ abc.xyz」|/bin/grep -v:0 $ – user1464409

+0

從文體上講,最好對環境變量使用大寫變量名稱,並使用小寫變量名稱作爲通用名稱。腳本中的SHOUTING較少。就個人而言,我可能會使用'$ opts'來代替'$ GREP_MY_OPTIONS';我儘可能避免使用代碼中的「我的」一詞(實際上大部分時間),但這是我的問題。最後(現在),如果我可能需要使用不同的'grep'程序,我通常使用:'grep =「$ {GREP:-grep}」'這允許環境變量GREP覆蓋缺省值。測試時我用'date'做了。 –

回答

1

如果構建了GREP_MY_OPTIONS作爲數組,而不是一個簡單的字符串,就可以得到原來的大綱腳本合理工作:

#!/bin/bash 
path="/home/user/this path has spaces in it" 
GREP="$(which grep)" 
GREP_MY_OPTIONS=("-c") 
j=1 
for i in {-2..2} 
do 
    GREP_MY_OPTIONS[$((j++))]="-e" 
    GREP_MY_OPTIONS[$((j++))]=$(date --date="$i day" +'%Y-%m-%d') 
done 

IFS=$'\n' 
MYARRAY=($(${GREP} "${GREP_MY_OPTIONS[@]}" "$path/"*"/abc.xyz" | ${GREP} -v :0$)) 

我不明白爲什麼你用GREP="$(which grep)",因爲你將執行同樣grep,如果你直接寫grep - 除非,我想,你有grep一些別名(它是那麼問題;別別名grep)。

3

如果你想grep在一組路徑一些內容,你可以做到以下幾點:

find <directory> -type f -print0 | 
    grep "/home/user/this path has spaces in it/\"*\"/abc.xyz" | 
    xargs -I {} grep <your_options> -f <patterns> {} 

這樣<patterns>是包含你想從directory每個文件中搜索模式的文件。

考慮你的答案,這應該做你想做的:

find "/path\ with\ spaces/" -type f | xargs -I {} grep -H -c -e 2013-01-17 {} 

man grep

-H, --with-filename 
      Print the file name for each match. This is the default when 
      there is more than one file to search. 

既然你要插入的元素融入到一個數組,你可以做到以下幾點:

IFS=$'\n'; array=($(find "/path\ with\ spaces/" -type f -print0 | 
    xargs -I {} grep -H -c -e 2013-01-17 "{}")) 

然後使用值爲:

echo ${array[0]} 
echo ${array[1]} 
echo ${array[...]} 

當使用變量傳遞參數時,使用eval來評估整條線。執行以下操作:

parameters="-H -c" 
eval "grep ${parameters} file" 
+0

感謝您的幫助Rubens,我是bash和grep以及Linux的新手。我試圖使用你的find命令,但我正在努力處理通配符的一部分,「find」正在抱怨「沒有這樣的文件或目錄」。 – user1464409

+0

@ user1464409你非常歡迎;我編輯了這個命令,以便你可以過濾你想要的「路徑」,只考慮那些匹配'/ home/user /這個路徑中有空格/「*」/ abc.xyz'的路徑。看看是否有效。 (請注意,沒有實際的換行符,它只是爲了避免滾動條)。 – Rubens

+0

好的,我把這個做了簡化: find/path \ with \ spaces/-type f | xargs -I {} grep -c -e 2013-01-17 {} 如上所述證明存在問題並且可能太複雜。現在我從grep輸出中收到的是匹配的數量。我需要的文件名和匹配數(以前報告爲:文件名:no_of_matches) – user1464409

0

你可以做一件事而不讓事情複雜:

首先做了更改目錄在腳本中像下面:

cd /home/user/this\ path\ has\ spaces\ in\ it/ 
$ pwd 
/home/user/this path has spaces in it 

$ cd "/home/user/this path has spaces in it/" 
$ pwd 
/home/user/this path has spaces in it 

然後在劇本中做你想做的事。

$(${GREP} ${GREP_MY_OPTIONS} */abc.xyz) 

編輯

[[email protected] stack1]$ ls -l 
total 4 
drwxr-xr-x 2 sgeorge eng 4096 Jan 19 06:05 test tesd 
[[email protected] stack1]$ cat test\ tesd/file 
SUKU 
[[email protected] stack1]$ grep SUKU */file 
SUKU 

編輯

[[email protected] stack1]$ find */* -print | xargs -I {} grep SUKU {} 
SUKU 
+0

這似乎是一個很好的簡單解決方案,但如果*返回的內容還包含空格會發生什麼? – user1464409

+0

查看我的最後編輯 – Suku

+0

感謝您的幫助Suku。我嘗試過實施你所建議的「cd技巧」,但是當我嘗試從MYARRAY中讀取項目時(使用「$ {MYARRAY [@]}」做echo $ i),它也失敗了。當我回顯內容時,它會再次在路徑中的任何空格處分割。 – user1464409