LINUX.ORG.RU

Bash, строки, совпадения

 , ,


0

2

Ребят, помогите со скриптом. Есть две переменные. В одной лежат имена машин. Например:«машина 1», «машина 2». Во второй лежит:«машина 1», «машина 2», «машина 3».

Как найти в этих двух переменных совпадения и вывести в результат именно то, что не совпадает, то есть «машина 3».

Главное это делать не в файлах. Смотрел uniq, sort, comm. Но это вроде бы для файлов.



Последнее исправление: zhinkor (всего исправлений: 2)

Такие скрипты лучше на питоне писать.

peregrine ★★★★★
()
f_compare(){
  local flag
  local i
  local k
  for i in ${1}; do
   flag=0
   for k in ${2}; do
     [[ "${i}" != "${k}" ]] && flag=1 || flag=0
   done
   [[ flag -ne 0 ]] && echo ${i}
  done
}

f_compare "${var1}" "${var2}"
f_compare "${var2}" "${var1}"

Не будет работать, если в имени машины есть пробел.

sudoapter
()
Ответ на: комментарий от zhinkor
f_compare(){
  local flag
  local i
  local k
  for i in ${1}; do
   flag=0
   for k in ${2}; do
    if [[ "${i}" == "${k}" ]]; then
      flag=1
      break
    fi
   done
   [[ flag -eq 0 ]] && echo ${i}
  done
}

f_compare "${var1}" "${var2}"
f_compare "${var2}" "${var1}"
sudoapter
()
Последнее исправление: sudoapter (всего исправлений: 1)
Ответ на: комментарий от sudoapter

С массивом получается приятней:

d2=($var2)

for s in $var1; do
        n=${#d2[*]}
        for j in ${!d2[*]}; do
                [[ $s = "${d2[j]}" ]] && unset 'd2[j]'
        done
        [[ n -eq ${#d2[*]} ]] && echo "$s"
done
for s in "${d2[@]}"; do
        echo "$s"
done

vodz ★★★★★
()
Ответ на: комментарий от zhinkor

Спасибо, тоже работает.

Не, это было не вам. Это была демонстрация, что можно чуть поменять и будет красивее.

А вам все представленные советы не рекомендую. Они все сломаются для var1='*'. Впрочем мой код можно переписать:

read -a d1 <<< "$var1"
read -a d2 <<< "$var2"

for s in "${d1[@]}"; do
        n=${#d2[*]}
        for j in ${!d2[*]}; do
                [[ $s = "${d2[j]}" ]] && unset 'd2[j]'
        done
        [[ n -eq ${#d2[*]} ]] && echo "$s"
done
for s in "${d2[@]}"; do
        echo "$s"
done

vodz ★★★★★
()
Ответ на: комментарий от madcore

если уж такая дотошность по поводу экранирования

Ну так взяли б и заэкранировали. Или по крайней мере предупредили ТСа.

vodz ★★★★★
()
Ответ на: комментарий от anonymous

В первом сообщении

Не будет работать, если в имени машины есть пробел.

и я исходя из этого.


А в ТЗ вообще не сказано, какой там делимитер или ещё что

madcore ★★★★★
()

pwsh


$a = 'a','b','c','e'
$b = 'a','c','d','f'

(compare $a $b).InputObject
d
f
b
e
anonymous
()
Ответ на: комментарий от madcore

вот же с экранироваием

Нет, блин, это же высший пилотаж и не догадаться...

И таки да, можно и попилотировать:

echo "${var1// /$'\n'}"$'\n'"${var2// /$'\n'}"  | sort | uniq -u

vodz ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.