1

很抱歉发布关于我昨天正在编写的同一脚本的另一个问题。

最初我在使用带空格的路径时遇到了问题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
4

1 回答 1

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 1awk -v st="$searchTerm" '$0~st{print NR}' "$a"then如果您仍然有问题,请重新发布。

于 2013-01-06T15:30:52.143 回答