如果我正在search的文件存在于多个位置,并且告诉用户位置(查找结果),我正在编写一个脚本,以便在该文件中出错。 所以我有一个像这样的发现:
file_location=$(find $dir -name $file -print)
我想这应该很简单,看看是否在多个地方find该文件,但我不能匹配什么发现用来分隔结果(有时看起来像空间和换行别人)。 因此,而不是匹配,我想看看$ file_location $ file中是否有任何字符。
我正在检查
echo "$file_location" | grep -q "${file}."; then
而这仍然不起作用。 所以我想我不在乎我用什么,除了我想捕获$ file_location作为查找的结果,然后检查。 你能提出一个好的方法吗?
found=$(find "$dir" -name "$file" -ls) count=$(wc -l <<< "$found") if [ "$count" -gt 1 ] then echo "I found more than one:" echo "$found" fi
对于找到的零匹配,由于不透明的方式,shell会使用$()运算符剥离尾随的换行符,所以仍然会收到1,所以实际上一行输出和零行输出都是一行。 请参阅xxd <<< "" ,以再次用作输入时演示自动附加换行符。 一个简单的方法是在字符串的开头添加一个假的换行符,所以不能有空字符串: found=$(echo; find …) ,然后从行数中减去一个。
编辑:我改变了-printf "%p\n"的用法,在我的答案 – 执行适当的换行符引用。 否则带有换行符的文件名会使计数变得困难。
像下面的东西,如果你想避免在EOL等错误
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[@]}"
如果您在find命令中指定了全名,则名称上的匹配将是唯一的。 也就是说,如果你说find -name "hello.txt" ,只会找到名为hello.txt文件。
你可以做的是类似的东西
find $dir -name $file -printf '.' ^^^^^^^^^^^
这将打印许多. 因为找到了匹配。 然后,看看有多少文件被找到这个名字,这只是一个计算作为输出得到的点数的问题。
如果你正在运行一个新的(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[@]}"
我建议使用:
find . -name blong.txt -print0
它告诉find与null \0字符一起加入它的输出。 使用带-F标志的awk或带-0标志的xargs更容易。
尝试:
N=0 for i in `find $dir -name $file -printf '. '` do N=$((N+1)) done echo $N