如果我要搜索的文件存在于多个位置,并且告诉用户位置(查找结果),我正在写一个我想要错误的脚本。所以我找到了一个像:
file_location=$(find $dir -name $file -print)
我认为查看文件是否在多个地方找到应该很简单,但我不能匹配查找用于分隔结果的内容(有时似乎是空格,而其他地方则是换行符)。因此,我想查看$ file_location中$ file之后是否有任何字符,而不是匹配。
我正在检查
echo "$file_location" | grep -q "${file}."; then
这仍然不起作用。所以我想我不关心我使用的东西,除了我想通过查找捕获$ file_location,然后检查。你能提出一个好方法吗?
答案 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
标记-F
或xargs
标记-0
,可以更轻松地使用。{/ p>
答案 5 :(得分:0)
尝试:
N=0
for i in `find $dir -name $file -printf '. '`
do
N=$((N+1))
done
echo $N