我正在开设一个课程项目!家庭作业文本如下:
编写一个shell脚本,它将一个单词和一个数字作为参数。 然后它检查当前目录中的所有文件,并找出哪些文件 至少包含给定单词的给定单词。
示例输出应为:
$myprog3.sh write 2
The file "./file-comp.sh" contains the word "write" 3 times.
The file "./homework.log" contains the word "write" 11 times.
我写了一些代码但是在将文件名读入数组时遇到问题。
count=`find . -type f -exec grep -H $word {} \; | wc -l`
read -a filearray <<< `find . -type f -exec grep -l "$word" {} \;`
read -a numarray <<< `find . -type f -exec grep -c "$word" {} \;`
size=${#filearray[@]}
echo "Array size is "$size""
for x in `seq 0 $size`
do
echo $x
echo "${filearray[x]}"
done
输出如下:
Array size is 5
0
./UntitledDocument.tex~
1
./Untitled
2
Document.tex
3
./wordcounter.sh
4
./wordcounter.sh~
5
对于ex:它应该看起来像Untitled Document.tex而不是
无标题
Document.tex
我该如何解决?
还有一个完整的问题,请你给我一个解决方案吗? 提前谢谢..
答案 0 :(得分:3)
文件名中的空格在分配给数组时会导致 split 。最简单的方法是将IFS
定义为不包含空格的内容。而不是说
read -a filearray <<< `find . -type f -exec grep -l "$word" {} \;`
说:
IFS=$'\n' read -a filearray <<< `find . -type f -exec grep -l "$word" {} \;`
答案 1 :(得分:1)
由于grep -Hc
将输出
file:number_of_ocurrencies
您可以按照以下方式执行此操作:
declare -A arr
while IFS=: read file count
do
arr["$file"]=$count #### "$file" to allow spaces on the names
done < <(find . -type f -exec grep -Hc "$word" {} \;)
这样你就有了一个关联数组
([file1]=>number_of_ocurrencies_file1 [file2]=>number_of_ocurrencies_file2)
然后你可以按如下方式循环:
for key in "${!arr[@]}"; do ### double quotes to accept keys with spaces
echo "$key = ${arr[$key]}"
done
答案 2 :(得分:0)
你分三次运行相同的命令!并且,find
命令可能需要很长时间才能运行。
我会看看你的循环,看看你是否可以在这一循环中完成所有步骤:
file_count=0
find . -type f -print0 | while read -d $'\0' file
do
((file_count+=1)) #Count the number of files processed
here be dragons...
echo "The '$file' file contains '$word' $word_count times"
done
-print0
参数用NUL字符分隔出文件名(文件名中不能包含的两个字符之一。为了额外的功劳,你能说出另一个吗?您将此管道传输到while read file
以读取文件名。 -d$'\0'
告诉read
分解空字符上的单词。
这不仅可以处理文件名中的空格,还可以处理制表符,双倍空格,字符返回,新行以及几乎任何可以混合到其中的内容。无论文件名有多么质朴,您都可以保证只读一个文件名。
将命令输出到while read
语句是一种相当有效的操作。它可以并行进行。也就是说,在输出命令的输出时,while
循环正在执行。仔细看看这个循环的结构,因为你将在shell脚本中一遍又一遍地看到它。
((...))
是一项数学运算。
这里是龙...... 是您填写逻辑以获取所需信息的地方。毕竟,这是一项家庭作业。但是,看起来您可以很好地处理shell脚本。
如果您必须拥有这两个数组,我会将find
的输出传输到数组中,然后使用该数组将您的信息放入numarray
和filearray
。它效率不高,但至少你没有三次运行find
命令。