我有两个变量:var1="1, 2, 3, 4"
和var2="3, 4, 5, 6"
。
我想得到一个新的,变量3$var1
,包含和之间的差异$var2
。
预期结果应该是var3=1, 2, 5, 6
。
我尝试过diff
但输出不是我想要的:
diff <(echo "$var1") <(echo "$var2")
1c1
< 1, 2, 3, 4
---
> 3, 4, 5, 6
var3
还有哪种解决方案允许我在不创建任何文件的情况下实现此目的?
答案1
有很多方法...
您可以使用
sort
、tr
unique
和paste
和$()
来执行它们,“将输出转换为变量”#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo " ${var1}, ${var2}" | tr ',' '\n' | sort | uniq -u | paste -sd,) echo $var3
1, 2, 5, 6
对于前面的每个命令,你可以使用例如阅读更多内容
man sort
您可以在 bash 数组中转换变量并对其进行操作(请将以下内容作为提示,因为有无数种方法可以实现它......)
#!/bin/bash#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" # here you transform the variable in array IFS=',' read -ra ADDR <<< "$var1" IFS=',' read -ra ADDR2 <<< "$var2" # then for each element in the 1st array you search if in the 2nd too SEP=""; var3="" for i in "${ADDR[@]}"; do Found=0 for j in "${ADDR2[@]}"; do [[ "$i" -eq "$j" ]] && Found=1 done [[ $Found == 0 ]] && { var3="$var3$SEP$i" ; SEP=", "; } done # then for each element in the 2nd array you search if in the 1st too for j in "${ADDR2[@]}"; do Found=0 for i in "${ADDR[@]}"; do [[ "$i" -eq "$j" ]] && Found=1 done [[ $Found == 0 ]] && { var3="$var3$SEP$j" ; SEP=", "; } done echo $var3
使用
awk
(或者准确地说gawk
)#!/bin/bash var1="1, 2, 3, 4"; var2="3, 4, 5, 6" var3=$(echo "$var1, $var2" | \ awk -F ',' '{for (i=1;i<=NF;i++) {A[$i]++;} } END{ SEP=""; for (i in A) {if (A[i]==1){ printf ("%s%s", SEP,i); SEP=", "} } }' ) echo $var3
笔记:第二个和第三个输出没有排序......
更新说明: ...并且$var1
你$var2
的诡异的( :-)
) 格式在逗号 ( ,
) 后有空格,因此您需要特别注意所有只使用一个字符作为分隔符的命令......如果, 1
第二个字符串中有一个,则此问题得到解决......您无法找到什么,man <command>
您可以尝试使用man bash
或使用help command
...
令人厌烦:
diff
风格,本着您的尝试精神......也许您可以搜索更舒适的输出格式(man diff
)diff --ignore-all-space \ <(echo "$var1" | tr ',' '\n' ) <(echo "$var2" | tr ',' '\n')\ | grep -v "^---" | grep -v "^[0-9c0-9]" | tr -d '<||>|| |' \ | paste -sd,
答案2
我没有时间进行完整解释,但是:
var1="1, 2, 3, 4"; var2="3, 4, 5, 6"
comm -3 <(grep -oP '\d+' <<<"$var1" | sort) <(grep -oP '\d+' <<<"$var2" | sort) |
tr -d '\t' |
paste -sd,
1,2,5,6
答案3
另外一个选择:
#!/usr/bin/bash
var1="1, 2, 3, 4"
var2="3, 4, 5, 6"
out=""
for num in `echo $var1,$var2 | tr -d " "| tr "," "\n " | sort | uniq | tr "\n" " "`
do
if (`grep -v $num <<< "$var1" >/dev/null 2>&1` || `grep -v $num <<< "$var2" >/dev/null 2>&1`)
then
out="$out,$num"
fi
done
echo $out | sed -e 's/,//'
然后运行
$ ./test.sh
1,2,5,6