VAR3=$(printf "%d\n" $VAR1 $VAR2 | sort | uniq -u | tr '\n' ' ' | sed 's/\s$//)
$ echo "$VAR3"
2 4
Основным недостатком является то, что :он оставляет только уникальные значения из переменной VAR1
. То есть, если $VAR1
имеет одно значение, повторяющееся несколько раз, это значение не появляется в $VAR3
, потому что оно не уникально.
Пример:
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable is empty
VAR3 = "" # because it is containing only unique values and `2` and `4` repeated few times in the `VAR1`, therefore, they are not unique.
# The right result should be
VAR3 = "2 2 4 4 4"
VAR3=$(printf "%s\n" $VAR2 | awk -v var1="$VAR1" '
{arr2[$1] = 1;}
END {
size = split(var1, arr1);
for(i = 1; i <= size; i++) {
if(!arr2[arr1[i]])
printf "%s ", arr1[i];
}
}' | sed 's/\s$//')
Пояснение
printf "%s\n" $VAR2
-преобразует $VAR2
в столбец -по одному значению в строке. awk...
-удаляет значения $VAR2
из $VAR1
.
{arr2[$1] = 1;}
-помещает все VAR2
значения (, переданные в awk
с помощью printf
), в массив, где значения становятся индексами массива. = 1
просто означает истинное-это значение существует. Этот трюк дает нам следующее поведение :первое вхождение значения создает элемент массива, затем, если то же значение появляется снова, оно переходит к тому же индексу массива, другими словами, элемент не изменяется, когда появляется то же значение несколько раз. Таким образом, в итоге мы имеем все уникальные значения из переменной VAR2
. Если VAR2="one three five"
, то arr2
будет :arr2[one] = 1, arr2[three] = 1, arr2[five] = 1
. END { size = split(var1, arr1);
-когда строки ввода закончились(VAR2
обработка завершена ), мы разбиваем VAR1
на массив -каждое значение переходит в отдельный элемент. Если VAR1="one two three four five"
, то мы получим следующий массив :arr1[1] = one, arr1[2] = two, arr1[3] = three...
, и так далее. Функция split
возвращает размер нового созданного массива. if(!arr2[arr1[i]]) printf "%s ", arr1[i];
-перебирает arr1
элементов и проверяет, имеет ли arr2
индекс для этого элемента. Например :i = 1; arr1[1] = "one"
, тогда arr2[arr1[i]]
это-arr2[one]
. Этот элемент существует, не печатайте его. i = 2; arr1[2] = "two"
. arr2[two]
не существует, так что выведите его. Таким образом, мы печатаем все значения из arr1
, которых нет в arr2
. sed 's/\s$//'
-удаляет завершающий пробел.
Плюсы этого способа по сравнению с первым вариантом:
# It can process strings
VAR1="one two three four five"
VAR2="one three five"
# the resulting VAR3 variable
VAR3 = "two four"
# It doesn't remove multiple occurrence of one value in the VAR1
VAR1="1 2 2 3 4 4 4 5"
VAR2="1 3 5"
# the resulting VAR3 variable
VAR3 = "2 2 4 4 4"
Xvfb является частью сервера xorg -
git clone https://salsa.debian.org/xorg-team/xserver/xorg-server.git