找到多少个文件?

how many files find found?

我正在编写一个脚本,如果我正在搜索的文件存在于多个位置,我想在其中出错,并告诉用户位置(查找结果)。所以我找到了这样的:

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

我认为查看是否在多个位置找到该文件应该很简单,但我必须不匹配 find 用于分隔结果的内容(有时看起来像 space,换行符其他)。因此,我不想匹配它,而是想看看 $file_location.

中的 $file 之后是否有任何字符

我正在检查

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

这仍然不起作用。所以我想我不在乎我使用什么,除了我想捕获 $file_location 作为查找的结果,然后检查它。能推荐个好方法吗?

我推荐使用:

find . -name blong.txt -print0

这告诉 find 将其输出与空 [=12=] 字符连接在一起。使 awk-F 标志或 xargs-0 标志一起使用变得更容易。

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

你可以做的是

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

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

尝试:

N=0

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

echo $N
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 strips 带有 $() 运算符的尾随换行符的不透明方式,所以实际上,一行输出和零行输出最终都是一行。有关再次用作输入时自动附加换行符的演示,请参阅 xxd <<< ""。一个简单的规避方法是在字符串的开头添加一个假的换行符,这样就不会出现空字符串:found=$(echo; find …),然后从行数中减去一个。

编辑:我在对 -ls 的回答中更改了 -printf "%p\n" 的用法,它执行正确的换行引用。否则带有换行符的文件名会弄乱计数。

如果你想避免 eols 等错误,可以像下面这样

files=() 
while IFS= read -d $'[=10=]' -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[@]}"

如果您是 运行 一个新的 (4.0+) bash,它可以自己进行递归 globbing,那么这里不需要 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[@]}"