LINUX.ORG.RU

Сравнение выводов команд в виде списков или массивов

 , ,


0

1

Здравствуйте. Я только изучаю bash, так что войдите в положение :) Хочу выделить уникальные для переменной 1 (именно переменной, а не файла) составляющие. Дано: var1 и var2, каждая из которых приравнивается к пайпу, результатом которого являются несколько строк, состоящих из 1 слова без пробелов. Что я пробую:

var1=$(... | ... | sort)
var2=$( ...| ... | sort)
comm -3 $var1 $var2

for i in $var1
do
    if ! [[ "$i" -eq "$var2" ]]
    then
        echo $i
    fi
done
for i in $var1
do
    if [[ "$i" -ne "$var2" ]]
    then
        echo $i
    fi
done
var1=($(... | ... | sort | tr "\n" " "))
var2=($( ...| ... | sort | tr "\n" " "))
for i in ${var1[*]}
do
    if [[ "$i" ~= "${var2[*]}" ]]
    then
        echo $i
    fi
done

Comm вроде только файлы выводит, но я попробовал на всякий случай. Все остальные варианты выводят все элементы, вместо уникальных... Подскажите, как правильно сделать.

Ответ на: комментарий от Minona

Нет это совсем не то. Вот пример

var1 вида
s1
s2
s3
s4
s5

var2 вида
s1
s3
s5
результат всех операций - вывод
s2
s4
При этом работа без записи данные в файлы, а только через переменные.

Novikov_A ()
Ответ на: комментарий от Minona

Ааа понял :)

Вам надо реализовать алгоритм вычитания множеств var1-var2.

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

Вам нужно 2 цикла, первый берет элементы из вар1, второй пробегает по вар2 ищет совпадения - не нашли, выводим в результат, нашли - прерываем поиск по вар2, переходим к следующему из вар1.

Minona ★★★ ()

Я только изучаю bash

У вас похоже не с bash проблема, а с программированием вообще. Ведь ясно, что надо вложенные циклы.

#!/bin/bash

var1=($(echo s1; echo s2; echo s3; echo s4; echo s5))
var2=($(echo s1; echo s3; echo s5))

for i1 in "${var1[@]}"; do
        found=
        for i2 in "${var2[@]}"; do
                if [[ "$i1" = "$i2" ]]; then
                        found=1
                        break
                fi
        done
        [[ -z $found ]] && echo "$i1"
done
vodz ★★★★★ ()
Ответ на: комментарий от vodz

Обратите внимание, сударь, на этот случай: ТС попробовал писать на баше как на обычном языке программирования с переменными и циклами и начисто провалил дело, напутав с

1) кавычками

2) '\n' и ' '

3) ${var1[*]} вместо ${var1[@]}

Поймёт ли он, почему в вашем решении используется echo s1; echo s3, а не echo s1 s3?

Вот именно поэтому я никогда не советую писать на sh/bash в императивном стиле, с явными циклами и переменными, если этого можно избежать.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)
Ответ на: комментарий от legolegs

ТС попробовал писать на баше как на обычном языке программирования с переменными и циклами

Вы подгоняете результат под свой бзик. Автор провалил алгоритм вообще. :)

Поймёт ли он, почему в вашем решении используется echo s1; echo s3, а не echo s1 s3?

Надеюсь, так как это я подстраивался под его входные данные. Я вообще мог бы поступить как ТС: написать троеточие, данные у него единственно что как-то записаны в таком виде, что его удовлетворяют :) Но вы видите разницу в результате? Я не вижу, так как IFS по умолчанию и пробелы и перевод строки. Смысл был только показать, что «| tr» потому и не нужено.

Вот именно поэтому я никогда не советую писать на sh/bash в императивном стиле

С учётом первого возражения, которое было в том комментарии, на который вы отвечали, ваша мысль пока бесполезна.

vodz ★★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)

Писать такое на баше мазохизм.

Любой язык подойдет с операциями над массивами

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

Путем трешовых манипуляций

Если делать, то инструментами для этого предназначенными

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