测试几个变量是否相等的正确方法是什么?
if [[ $var1 = $var2 = $var3 ]] # syntax error
是否有必要写下面的内容?
if [[ $var1 = $var2 && $var1 = $var3 && $var2 = $var3 ]] # cumbersome
if [[ $var1 = $var2 && $var2 = $var3 && $var3 = $var4 ]] # somewhat better
不幸的是,我能找到的优秀的Advanced Bash Scripting Guide和其他在线资源并没有提供这样的例子。
我的特别动机是测试几个目录是否都有相同数量的文件,使用ls -1 $dir | wc -l
来计算文件。
注意
“var1”等是示例变量。我正在寻找任意变量名称的解决方案,而不仅仅是具有可预测数字结尾的变量名称。
更新
我接受了Richo的答案,因为它是最普遍的。但是,我实际上是在使用Kyle,因为它是最简单的,我的输入可以保证避免警告。
感谢大家的建议。
答案 0 :(得分:3)
如果你想测试任意数量项目的相等性(我们称之为$ item1-5,但它们可能是一个数组
st=0
for i in $item2 $item3 $item4 $item5; do
[ "$item1" = "$i" ]
st=$(( $? + st ))
done
if [ $st -eq 0 ]; then
echo "They were all the same"
fi
答案 1 :(得分:2)
如果它们是单个单词,你可以非常便宜。
varUniqCount=`echo "${var1} ${var2} ${var3} ${var4}" | sort -u | wc -l`
if [ ${varUniqCount} -gt 1 ]; then
echo "Do not match"
fi
答案 2 :(得分:1)
(编辑包括用于解决Keith Thompson注意到的问题的分隔符)
将变量值作为字符串处理,您可以将它们与合适的分隔符连接起来并进行一次比较:
if [[ "$var1|$var2|$var3" = "$var1|$var1|$var1" ]]
我使用=而非= =因为==不是[[]]内的相等比较,它是一种模式匹配。
答案 3 :(得分:1)
检查的传递方法。
#!/bin/bash
var1=10
var2=10
var3=10
if [[ ($var1 == $var2) && ($var2 == $var3) ]]; then
echo "yay"
else
echo "nay"
fi
[jaypal:~/Temp] ./s.sh
yay
由于您已在问题中声明您的目标是测试具有相同数量文件的多个目录,因此我想到了以下解决方案。我知道这不是你要求的,所以请随意忽略它。
确定给定目录中的文件数。此命令也会查看子目录内部,但可以使用-depth
find
选项控制该命令。
[jaypal:~/Temp] find . -type d -exec sh -c "printf {} && ls -1 {} | wc -l " \;
. 9
./Backup 7
./bash 2
./GTP 22
./GTP/ParserDump 11
./GTP/ParserDump/ParserDump 1
./perl 7
./perl/p1 2
./python 1
./ruby 0
./scripts 22
这可以与Step1
结合使用,因为我们只是将内容重定向到文件。
[jaypal:~/Temp] find . -type d -exec sh -c "printf {} && ls -1 {} | wc -l " \; > file.temp
使用以下命令,我们将在file.temp中查看两次,它将为我们提供具有相同文件数的目录列表。
[jaypal:~/Temp] awk 'NR==FNR && a[$2]++ {b[$2];next} ($2 in b)' file.temp file.temp | sort -k2
./GTP/ParserDump/ParserDump 1
./python 1
./bash 2
./perl/p1 2
./Backup 7
./perl 7
./GTP 22
./scripts 22
答案 4 :(得分:1)
对于您的具体情况,这应该有效:
distinct_values=$(for dir in this_dir that_dir another_dir ; do ls -l "$dir" | wc -l ; done | uniq | wc -l)
if [ $distinct_values -eq 1 ] ; then
echo All the same
else
echo Not all the same
fi
说明:
ls -l "$dir"
列出目录中的文件和子目录,每行一个(省略点文件)。wc -l
管道输出为您提供目录中的文件数。7
uniq
进行管道消除了连续的重复行。wc -l
会为您提供不同行的数量,当且仅当所有目录包含相同数量的文件时才会为1。请注意,第4阶段的输出不一定能为您提供目录中不同数量的文件数量; uniq
仅删除相邻的重复项,因此如果输入为7 6 7
,则两个7
将不会合并。但如果它们全部相同,它会将所有行合并为1 。
这是Unix命令行的强大功能:将小工具放在一起做有趣且有用的事情。 (给我看一个可以做到这一点的GUI!)
对于存储在变量中的值,请将第一行替换为:
distinct_values=$(echo "$this_var" "$that_var" "$another_var" | fmt -1 | uniq | wc -l)
这假设变量的值不包含空格。