Вопрос или проблема
Для справки, это продолжение ответа @EdMorton на мой предыдущий вопрос: сделать master/slave ip в разных подсетях
У меня есть файл с дубликатами в первом и втором столбцах, мне нужно получить строки, в которых первый столбец уникален, а второй столбец уникален. Может быть несколько результатов, но это не проблема.
a d
a e
b f
b e
c f
c d
желаемый выход:
a e
b f
c d
или
a d
b e
c f
Я попробовал следующий код, но получил только две строки на выходе:
a d
b f
declare -A left_ips
declare -A right_ips
results=()
while read -r line; do
left_ip=$(echo "$line" | awk '{print $1}')
right_ip=$(echo "$line" | awk '{print $2}')
if [[ -z "${left_ips[$left_ip]}" && -z "${right_ips[$right_ip]}" ]]; then
results+=("$line")
left_ips[$left_ip]=1
right_ips[$right_ip]=1
fi
done < /tmp/tmp.txt
for result in "${results[@]}"; do
echo "$result"
done
Ответ или решение
Чтобы извлечь уникальные строки из файла, где сочетания значений из первого и второго столбца являются уникальными, можно воспользоваться языком программирования Bash. В вашем случае, вы хотите получить уникальные строки, где значения в первом столбце не повторяются, но также были учтены значения во втором столбце. В результате у вас должен получиться файл с несколькими уникальными строками.
Основная идея решения состоит в том, чтобы использовать ассоциативные массивы для отслеживания встреченных значений в обоих столбцах. Давайте рассмотрим решение подробно.
Шаги для решения задачи
- Создание ассоциативных массивов для хранения уникальных значений из первого и второго столбца.
- Чтение файла построчно, и для каждой строки:
- Извлечение первого и второго столбца.
- Проверка, встречалось ли уже значение первого столбца и второго столбца.
- Если оба значения уникальны, сохранить строку в результирующий массив и отметить, что они были встречены.
- Вывод уникальных строк.
Пример кода
#!/bin/bash
# Ассоциативные массивы для хранения уникальных значений
declare -A left_ips
declare -A right_ips
results=()
# Чтение входного файла
while read -r line; do
left_ip=$(echo "$line" | awk '{print $1}')
right_ip=$(echo "$line" | awk '{print $2}')
# Проверка уникальности
if [[ -z "${left_ips[$left_ip]}" && -z "${right_ips[$right_ip]}" ]]; then
results+=("$line") # Добавление строки к результатам
left_ips[$left_ip]=1 # Пометка первого столбца как встреченного
right_ips[$right_ip]=1 # Пометка второго столбца как встреченного
fi
done < /path/to/your/file.txt # Указать путь к вашему файлу
# Вывод результатов
for result in "${results[@]}"; do
echo "$result"
done
Как это работает
- Ассоциативные массивы:
left_ips
иright_ips
используются для отслеживания, были ли встречены значения из первого и второго столбца. - Условие проверки: Если значения обоих столбцов не встречались ранее (
if [[ -z "${left_ips[$left_ip]}" && -z "${right_ips[$right_ip]}" ]]
), это значит, что они уникальны, и текущая строка может быть добавлена в результат.
Возможные результаты
При выполнении данного скрипта на входных данных, приведённых в вашем примере, может быть получено несколько различных выходных строк, которые соответствуют уникальным парам из первого и второго столбца:
a e
b f
c d
или
a d
b e
c f
Заключение
Данный подход позволяет эффективно обрабатывать данные для получения уникальных записей из файла. Убедитесь, что вы передаете корректный путь к вашему файлу, чтобы избежать ошибок во время исполнения. Этот код является простым и эффективным методом для извлечения уникальных строк из текста в Unix-подобных операционных системах.