Shell脚本问题,文件名在读入数组时包含空格

时间:2013-10-17 12:01:26

标签: bash shell

我正在开设一个课程项目!家庭作业文本如下:

编写一个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

我该如何解决?

还有一个完整的问题,请你给我一个解决方案吗? 提前谢谢..

3 个答案:

答案 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

部分基于Bash script “find” output to array

答案 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的输出传输到数组中,然后使用该数组将您的信息放入numarrayfilearray。它效率不高,但至少你没有三次运行find命令。