找到多少个文件?

时间:2015-07-31 21:37:40

标签: bash unix find

如果我要搜索的文件存在于多个位置,并且告诉用户位置(查找结果),我正在写一个我想要错误的脚本。所以我找到了一个像:

file_location=$(find $dir -name $file -print)

我认为查看文件是否在多个地方找到应该很简单,但我不能匹配查找用于分隔结果的内容(有时似乎是空格,而其他地方则是换行符)。因此,我想查看$ file_location中$ file之后是否有任何字符,而不是匹配。

我正在检查

echo "$file_location" | grep -q "${file}."; then

这仍然不起作用。所以我想我不关心我使用的东西,除了我想通过查找捕获$ file_location,然后检查。你能提出一个好方法吗?

6 个答案:

答案 0 :(得分:2)

如果您想避免在eols上出现错误等,请执行以下操作

files=() 
while IFS= read -d $'\0' -r match; do 
  files+=("$match") 
done < <(find "$dir" -name "$file" -print0) 
(${#files[@]} > 1) && printf '%s\n' "${files[@]}"

或者在bash 4 +

shopt -s globstar dotglob 
files=("$dir"/**/"$file") 
((${#files[@]} > 1)) && printf '%s\n' "${files[@]}"

答案 1 :(得分:1)

如果在find命令中指定全名,则名称上的匹配项将是唯一的。也就是说,如果您说find -name "hello.txt",则只会找到名为hello.txt的文件。

你能做的就是

find $dir -name $file -printf '.'
                      ^^^^^^^^^^^

这将打印与匹配项一样多的.。然后,要查看使用此名称找到多少文件,只需计算您获得的点数作为输出。

答案 2 :(得分:1)

found=$(find "$dir" -name "$file" -ls)
count=$(wc -l <<< "$found")
if [ "$count" -gt 1 ]
then
  echo "I found more than one:"
  echo "$found"
fi

对于零匹配,发现你仍然会收到1,因为shell $()运算符剥离尾随换行符的不透明方式,因此有效的一行输出和零行输出是最后都是一条线。有关再次用作输入时换行符自动附加的演示,请参阅xxd <<< ""。避免这种情况的一种简单方法是在字符串的开头添加一个伪换行,这样就不会出现空字符串:found=$(echo; find …),然后从行数中减去一行。

编辑:我在-printf "%p\n"的答案中更改了-ls的使用情况,该self.kwargs['year']会正确引用换行符。否则,带有换行符的文件名会使计数混乱。

答案 3 :(得分:1)

如果您正在运行一个可以执行递归通配的新(4.0+)bash,则此处不需要find;只需将glob结果直接加载到shell数组中,并检查其长度:

shopt -s nullglob globstar # enable recursive globbing, and null results
file_locations=( "$dir"/**/"$file" )
echo "${#file_locations[@]} files named $file found under $dir; they are:"
printf '  %q\n' "${file_locations[@]}"

如果你不想弄乱nullglob,那么:

shopt -s globstar # enable recursive globbing
file_locations=( "$dir"/**/"$file" )

# without nullglob, a failed match will return the glob expression itself
# to test for this, see if our first entry exists
if [[ -e ${file_locations[0]} ]]; then
  echo "No instances of $file found under $dir"
else
  echo "${#file_locations[@]} files named $file found under $dir; they are:"
  printf '  %q\n' "${file_locations[@]}"
fi

您仍然可以使用数组明确地读取旧版本bash上的find结果;与更天真的方法不同,即使文件或目录名称包含文字换行符,这也会起作用:

file_locations=( )
while IFS= read -r -d '' filename; do
  file_locations+=( "$filename" )
done < <(find "$dir" -type f -name "$file" -print0)
echo "${#file_locations[@]} files named $file found under $dir; they are:"
printf '  %q\n' "${file_locations[@]}"

答案 4 :(得分:0)

我建议使用:

find . -name blong.txt -print0

告诉find将其输出与空\0个字符一起加入。通过awk标记-Fxargs标记-0,可以更轻松地使用。{/ p>

答案 5 :(得分:0)

尝试:

N=0

for i in `find $dir -name $file -printf '. '`
do
    N=$((N+1))
done

echo $N