检查变量是否匹配,如果不匹配则找出差异
Check if variables are matching and if not find the difference
我有 2 个变量的数据。
var1='abc;mno;def'
var2='mno;xyz'
** var2 can also be 'def;mno;abc'
我想比较 var1 和 var2
if [[ $var1=$var2 ]]
then
echo "MATCHED"
else
echo "Not Matched"
fi
这会给我基本的验证,但我的要求有点不同。我想要数据存在于 var1 中但在 var2 中丢失以及数据存在于 var2 中但在 var1
中丢失
我想要以下格式的数据:
abc;mno;def,mno;xyz,Not Matched,abc;def(## data present in var1 but missing in var2),xyz(data present in var2 but missing in var1)
第二种情况
var1='abc;mno;def'
var2='def;mno;abc'
输出
abc;mno;def,def;mno;abc,Matched, ,
任何建议都很好。
假设您正在使用 bash
,请您尝试以下操作:
#!/bin/bash
var1='abc;mno;def'
var2='mno;xyz'
#var2='def;mno;abc'
while IFS=';' read -r c1 c2 c3; do
[[ -n $c1 ]] && col1+=("$c1") # present in var1 only
[[ -n $c2 ]] && col2+=("$c2") # present in var2 only
[[ -n $c3 ]] && col3+=("$c3") # present in both var1 and var2
done < <(comm <(tr ';' '\n' <<< "$var1" | sort) <(tr ";" "\n" <<< "$var2" | sort
) | tr '\t' ';')
if (( ${#col1[@]} == 0 && ${#col2[@]} == 0 )); then
msg="Matched" # both col1 and col2 are empty
else
msg="Not Matched"
fi
printf "%s,%s,%s,%s,%s\n" "$var1" "$var2" "$msg" \
"$(IFS=';'; echo "${col1[*]}")" "$(IFS=';'; echo "${col2[*]}")"
输出:
abc;mno;def,mno;xyz,Not Matched,abc;def,xyz
第二种情况的输出:
abc;mno;def,def;mno;abc,Matched,,
tr ';' '\n' <<< "$var1" | sort
将 $var1
分成排序的行
要提供给 comm
的数据。与 $var2
. 相同
comm <(...) <(...)
比较两个输入然后将数据排序为
三列取决于数据的唯一性。
- 制表符,
comm
输出的字段分隔符,被替换
使用 ;
可以使用 read
命令正确处理。否则 read
将跳过前导字段分隔符。
- 第一列的数据(
var1
独有)累积在
数组 col1
。与 col2
和 col3
. 相同
- 我们可以通过检查长度来检查
$var1
和 $var2
是否匹配
数组 col1
和 col2
。如果两者都为空,则变量匹配。
这里有一个awk
替代方案,仅供参考:
#!/bin/bash
var1='abc;mno;def'
var2='mno;xyz'
#var2='def;mno;abc'
awk -v var1="$var1" -v var2="$var2" '
BEGIN {
split(var1, ai, ";") # split var1 on ";"
split(var2, bi, ";") # same as above
for (i in ai) a[ai[i]] # generate associavive array
for (i in bi) b[bi[i]] # same as above
for (i in a) {
if (! (i in b)) { # seen in a, not b
uniq1[i] # then store it in uniq1
}
}
for (i in b) {
if (! (i in a)) { # seen in b, not a
uniq2[i] # then store it in uniq2
}
}
fs = ""
for (i in uniq1) { # join elements of uniq1 with ";"
u1 = u1 fs i # into a string u1
fs = ";"
}
fs = ""
for (i in uniq2) { # join elements of uniq2 with ";"
u2 = u2 fs i # into a string u2
fs = ";"
}
msg = (length(u1) == 0 && length(u2) == 0)? "Matched" : "Not Matched"
printf("%s,%s,%s,%s,%s\n", var1, var2, msg, u1, u2)
}'
我有 2 个变量的数据。
var1='abc;mno;def'
var2='mno;xyz'
** var2 can also be 'def;mno;abc'
我想比较 var1 和 var2
if [[ $var1=$var2 ]]
then
echo "MATCHED"
else
echo "Not Matched"
fi
这会给我基本的验证,但我的要求有点不同。我想要数据存在于 var1 中但在 var2 中丢失以及数据存在于 var2 中但在 var1
中丢失我想要以下格式的数据:
abc;mno;def,mno;xyz,Not Matched,abc;def(## data present in var1 but missing in var2),xyz(data present in var2 but missing in var1)
第二种情况 var1='abc;mno;def' var2='def;mno;abc'
输出
abc;mno;def,def;mno;abc,Matched, ,
任何建议都很好。
假设您正在使用 bash
,请您尝试以下操作:
#!/bin/bash
var1='abc;mno;def'
var2='mno;xyz'
#var2='def;mno;abc'
while IFS=';' read -r c1 c2 c3; do
[[ -n $c1 ]] && col1+=("$c1") # present in var1 only
[[ -n $c2 ]] && col2+=("$c2") # present in var2 only
[[ -n $c3 ]] && col3+=("$c3") # present in both var1 and var2
done < <(comm <(tr ';' '\n' <<< "$var1" | sort) <(tr ";" "\n" <<< "$var2" | sort
) | tr '\t' ';')
if (( ${#col1[@]} == 0 && ${#col2[@]} == 0 )); then
msg="Matched" # both col1 and col2 are empty
else
msg="Not Matched"
fi
printf "%s,%s,%s,%s,%s\n" "$var1" "$var2" "$msg" \
"$(IFS=';'; echo "${col1[*]}")" "$(IFS=';'; echo "${col2[*]}")"
输出:
abc;mno;def,mno;xyz,Not Matched,abc;def,xyz
第二种情况的输出:
abc;mno;def,def;mno;abc,Matched,,
tr ';' '\n' <<< "$var1" | sort
将$var1
分成排序的行 要提供给comm
的数据。与$var2
. 相同
comm <(...) <(...)
比较两个输入然后将数据排序为 三列取决于数据的唯一性。- 制表符,
comm
输出的字段分隔符,被替换 使用;
可以使用read
命令正确处理。否则read
将跳过前导字段分隔符。 - 第一列的数据(
var1
独有)累积在 数组col1
。与col2
和col3
. 相同
- 我们可以通过检查长度来检查
$var1
和$var2
是否匹配 数组col1
和col2
。如果两者都为空,则变量匹配。
这里有一个awk
替代方案,仅供参考:
#!/bin/bash
var1='abc;mno;def'
var2='mno;xyz'
#var2='def;mno;abc'
awk -v var1="$var1" -v var2="$var2" '
BEGIN {
split(var1, ai, ";") # split var1 on ";"
split(var2, bi, ";") # same as above
for (i in ai) a[ai[i]] # generate associavive array
for (i in bi) b[bi[i]] # same as above
for (i in a) {
if (! (i in b)) { # seen in a, not b
uniq1[i] # then store it in uniq1
}
}
for (i in b) {
if (! (i in a)) { # seen in b, not a
uniq2[i] # then store it in uniq2
}
}
fs = ""
for (i in uniq1) { # join elements of uniq1 with ";"
u1 = u1 fs i # into a string u1
fs = ";"
}
fs = ""
for (i in uniq2) { # join elements of uniq2 with ";"
u2 = u2 fs i # into a string u2
fs = ";"
}
msg = (length(u1) == 0 && length(u2) == 0)? "Matched" : "Not Matched"
printf("%s,%s,%s,%s,%s\n", var1, var2, msg, u1, u2)
}'