我的shell脚本问题......(grep)

时间:2013-01-06 13:44:27

标签: bash shell grep

我很抱歉用我昨天工作的相同脚本发布了另一个问题。

最初我遇到了cd带有空格的路径的问题,尽管现在已经修复了。问题是,如果给脚本一个第三个参数,那就是在它之前找到的文件中搜索它,然后打印文件位置以及找到该术语的行号。

由于某种原因,grep不喜欢包含空格的文件的路径(再次正确?-.-),即使我已经双引号变量grep

有没有人对如何修复它有任何想法?

#!/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

1 个答案:

答案 0 :(得分:1)

您的脚本有很多问题,包括未引用和错误引用的变量。以下是你的getFiles函数需要写入的最小值(还有其他一些问题,比如grep是否真的有必要和echo的使用,但我没有触及那些因此这突出了严重的问题):

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",然后重新发布。