我很抱歉用我昨天工作的相同脚本发布了另一个问题。
最初我遇到了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
答案 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"
,然后重新发布。