2013-01-06 139 views
1

我很抱歉發佈了與我昨天工作的腳本有關的另一個問題。我的shell腳本的問題...(grep)

最初我對它有問題cd ing帶有空格的路徑,雖然現在已經修復了。問題是,如果給腳本第三個參數,它將在它之前找到的文件中搜索它,然後打印文件位置以及找到該術語的行號。

出於某種原因grep不喜歡路徑包含空格的文件(再次對不對?-.-),即使我有雙引號的變量我grep ING。

有沒有人有關於如何解決它的任何想法?

#!/bin/bash 

path = $1 #1st arg is the path to be searched 
regex = $2 #2nd arg is a regular expression 
searchTerm = $3 #3rd arg is an optional search term 
startDir = `pwd` #Stores the starting path 
getDirs() 
{ #Function to get the directories 
    for i in "$1" 
    ; do 
     if [ -d "$i" ]; then 
      echo "$i" >> temp.txt 
      getDirs "$i" 
     fi 
    done 
} 

getFiles() {  # Function to get files matching the regex 

    while IFS= read -r path; do # While there is a line, read it, backslash is not a delimiter 
     cd "$path" 

     temp=`ls -1 | grep "$regex"` #List the contents of the dir. Store only files that match the regex 

     for j in $temp 
     do 
      echo "$path/$j" # For every file stored, print its location 
     done 
     cd $startDir 
    done < temp.txt # Read from temp.txt 
} 

searchFiles() { # Function to search within files 


    for a in $output1 # For every file found 
    do 
     out=`grep -n "$searchTerm" "$a" | cut -d: -f 1` # Find the line numbers in which it is present, stop showing after 1st : 
     for i in $out # For every line found 
     do 
      echo "$a: line $i" # Print the file location, and the line numbers of the terms 
     done 
    done 
} 

numArgs=$# 

echo "$path" >> temp.txt 
getDirs $path # Getting directories to search 

output1=`getFiles` 

cd $startDir 

if [ $numArgs == 3 ] # If a search term is specified 
then 
    searchFiles # Then search the files for it 
else 
    echo "$output1" # Otherwise, just print the location of the files 
fi 

rm temp.txt # Removing temporary files 
exit 0 
+2

請在此處發佈您的代碼,而不是通過鏈接。如果它看起來太長,那就是!你需要把它減少到最小的測試用例。 –

+0

我已經添加了代碼:) –

+0

我很確定問題是與searchFiles函數,這就是我的grep是 –

回答

1

你的腳本有問題,包括未加引號,並錯誤地引用變量很多。這是你的GetFiles功能如何需要至少要寫入(有喜歡的grep是否真的有必要和使用回聲等問題,但我不碰那些所以這凸顯了嚴重的問題):

getFiles() {  # Function to get files matching the regex 

    while IFS= read -r path; do # While there is a line, read it, backslash is not a delimiter 

     if cd "$path"; then 

      oIFS="$IFS" # save then reset and restore IFS to avoid work splitting on spaces, except newlines. 
      IFS=$'\n' tempA=($(ls -1 | grep "$regex")) #List the contents of the dir. Store only files that match the regex 
      IFS="$oIFS" 

      for j in "${tempA[@]}" 
      do 
       echo "$path/$j" # For every file stored, print its location 
      done 
      cd "$startDir" 

     fi 

    done < temp.txt # Read from temp.txt 
} 

注「temp」現在是一個數組,而不是一個字符串,因此您可以一次訪問它所包含的文件名,但仍然會引用它們中的每一個。我只是將它重命名爲tempA,使它明顯是一個數組。

因此,更新您的腳本以使用數組而不是字符串來保存上面演示的文件名,擺脫作業周圍的空間,引用所有變量,使用$(...)而不是反引號,並將grep -n "$searchTerm" "$a" | cut -d: -f 1更改爲awk -v st="$searchTerm" '$0~st{print NR}' "$a",然後在您仍有問題時重新發布。

+0

謝謝你的幫助,我剛剛介紹給大學的Bash相對較新,幾乎教給我們自己,所以我對任何可怕的不好的道歉:)我已經設法讓我的原始腳本通過使用'sed'處理路徑中的空間來工作。儘管我會盡力實施你給我的改進,但我需要練習!謝謝你的建議:) –

+1

幫你一個忙,不要用你描述的方式去做,就像擁有一輛自行車,隨身攜帶它 - 你可以做到,但人們會看你有點有趣!由此產生的腳本也無法幫助解決bug並且將來難以增強/維護,因爲它使用的工具根本不是爲工作而設計的,並且如果您發佈一個請求幫助的問題,就會猜測迴應將會在這裏。 –

+0

請注意,您的示例代碼在這裏仍然存在包含空白的文件。 'tempA =($(ls -1 | grep ...))'表達式將經歷分詞。 –