我的bash中有两个数组,每个都包含文件。在我的循环中,有时文件会被删除。每当发生这种情况时,其中一个数组显示旧状态,另一个数组显示新状态。我如何设法显示它们之间的差异,例如: G。哪个文件确切删除了?顺便说一句,没有其他方法可以找到。
以下是一个例子:
arr_a=( file1.txt file2.txt file3.txt )
arr_b=( file1.txt file3.txt )
#Now the output should be file2.txt
我想到了一些好莱坞echo ${arr_a[@]#arr_b[@]}
,但这不起作用。 (这导致arr_a完全输出。)
答案 0 :(得分:1)
这个有点复杂但在数组不保持相关性的情况下会起作用。它将较大数组的所有元素排序为与较短数组中的元素相关联,然后在较大数组中打印其余元素(它适用于数组的副本)。未经充分测试:
#!/bin/bash
arr_a=( file1.txt file2.txt file3.txt )
arr_b=( file1.txt file3.txt )
sortarr() {
local sorted=( ${!1} ) sortby=( ${!2} )
local length=${#sorted[@]} i=${#sortby} matches
while (( i-- )); do
[[ ! "${sorted[@]}" =~ ${sortby[$i]} ]] && continue
sorted=( ${sorted[@]//$BASH_REMATCH/} )
printf -v matches '%*s' $(( $length - ${#sorted[@]} ))
sorted=( ${matches// /$BASH_REMATCH }${sorted[@]} )
done
for (( i=${#sortby[@]}; i<${#sorted[@]}; i++ )); do
echo ${sorted[$i]}
done
}
if (( ${#arr_a[@]} > ${#arr_b[@]} )); then
sortarr arr_a[@] arr_b[@]
else
sortarr arr_b[@] arr_a[@]
fi
答案 1 :(得分:0)
@David:你基本上需要的是两组之间的区别。使用一点python可以更轻松地完成此操作,如下面的方法0所示。方法-1和2只是使用Bash索引和稀疏数组的两种变体。以下每种方法的输出均为file2.txt
方式-0:强>
#!/bin/bash
arr_a=( file1.txt file2.txt file3.txt )
arr_b=( file1.txt file3.txt )
echo -e "${arr_a[@]} \n ${arr_b[@]}" | python -c '\
a=set(raw_input().strip().split());\
b=set(raw_input().strip().split());\
(x,y)=(a,b) if len(a)>len(b) else (b,a);\
print "".join(list(x-y));'
方式-1:强>
#!/bin/bash
arr_a=( file1.txt file2.txt file3.txt )
arr_b=( file1.txt file3.txt )
i=0
for a in ${arr_a[@]}
do
AinB=0
for b in ${arr_b[@]}
do
if [[ $a == $b ]]
then
AinB=1
fi
done
if [[ AinB -eq 0 ]]
then
arr_c[$((i++))]=$a
fi
done
echo ${arr_c[@]}
方式-2:强>
#!/bin/bash
arr_a="file1.txt file2.txt file3.txt"
arr_b="file1.txt file3.txt"
arr_c=""
for a in $arr_a
do
isPresentInB=0
for b in $arr_b
do
if [[ $a == $b ]]
then
isPresentInB=1
break
fi
done
if [[ $isPresentInB -eq 0 ]]
then
arr_c="$arr_c $a"
fi
done
echo $arr_c
答案 2 :(得分:0)
这可能对您有用:
arr_a=(file1.txt file2.txt file3.txt)
arr_b=(file1.txt file3.txt)
answer=$(comm -3 <(printf "%s\n" "${arr_a[@]}") <(printf "%s\n" "${arr_b[@]}")
echo "$answer"
file2.txt
或许明智的做法是更加强大:
arr_answer=($(comm -3 <(printf "%s\n" "${arr_a[@]}") <(printf "%s\n" "${arr_b[@]}") | paste -sd' '))
((${#arr_answer[@]}==1)) && echo "$arr_answer" || echo "oops! wrong answer"