Цикл bash, приводящий к нежелательным повторяющимся результатам

Я работаю в баше. Я пытаюсь найти уникальные штрих-коды в строках в файле .txt. Каждая строка может содержать 3 штрих-кода. Я хочу идентифицировать и маркировать каждую уникальную конфигурацию, которая содержит интересующие меня штрих-коды.

Это мой начальный файл reads.txt, содержащий строки, которые я хочу оценить.

ABCD1
EFGH2
ABGH1
EFCD2

Например, штрих-коды, содержащиеся в ABCD1, - это AB, CD и 1.

Мой желаемый результат - идентифицировать только цепочки ABCD1 и EFGH2 и хранить каждую из них соответственно как result.1.txt и result.2.txt.

Беллоу - это моя попытка.

# Add the barcode sequences to a bash array
declare -a BARCODES1=(AB EF)
declare -a BARCODES2=(CD GH)
declare -a BARCODES3=(1 2)

# Initialize counter
count=1

# Search for the barcode sequences in the reads.txt file
rm ROUND*
rm result*

for barcode in "${BARCODES1[@]}";
    do
    grep "$barcode1" reads.txt > ROUND1_MATCHES.txt

        for barcode2 in "${BARCODES2[@]}";
        do
        grep "$barcode2" ROUND1_MATCHES.txt > ROUND2_MATCHES.txt

           for barcode3 in "${BARCODES3[@]}";
            do
            grep "$barcode3" ROUND2_MATCHES.txt > ROUND3_MATCHES.txt

                if [ -s ROUND3_MATCHES.txt ]
                then
                mv ROUND3_MATCHES.txt result.$count.txt
                fi

            count=`expr $count + 1`
            done
        done
    done

Как ни странно, этот код выводит слишком много файлов результатов. Запуск head results* дает мне следующее.

==> result.1.txt <==
ABCD1

==> result.2.txt <==
EFCD2

==> result.3.txt <==
ABGH1

==> result.4.txt <==
EFGH2

==> result.5.txt <==
ABCD1

==> result.6.txt <==
EFCD2

==> result.7.txt <==
ABGH1

==> result.8.txt <==
EFGH2

Желаемый результат был бы

==> result.1.txt <==
ABCD1

==> result.2.txt <==
EFCD2

Не связано, но почему именно в bash?

Dave Newton 13.09.2018 16:13

Я использовал bash, потому что он хорошо работает в среде кластера Linux, которую я использую, и потому что мне удобнее писать сценарии bash, чем на других языках (я все еще новичок). Конечно, что-то в python можно заставить работать. Есть ли очевидное преимущество (скорость и т. д.), Которое я упускаю, выбирая bash?

Paul 13.09.2018 16:21

¯_ (ツ) _ / ¯ Не знаю, просто кажется слишком сложным и тяжелым, чтобы продолжать использовать grepping / etc вместо использования более универсального языка с лучшей поддержкой строк и т. д.

Dave Newton 13.09.2018 16:24

Использование grep внутри вложенного внутреннего цикла (запуск целой новой программы, чтение входного файла с самого начала и т. д.) Действительно является серьезным запахом кода. Однако это не обязательно проблема с bash, а не проблема с тем, как он применяется.

Charles Duffy 13.09.2018 17:18
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
189
1

Ответы 1

Вы просто хотите перебрать индексы массивов:

for index in "${!BARCODES1[@]}"; do
    echo "${BARCODES1[index]}${BARCODES2[index]}${BARCODES3[index]}"
done
ABCD1
EFGH2

С 3 циклами вложенныйcount увеличивается в 2 * 2 * 2 = 8 раз


Немного неясно, что вы пытаетесь сделать: если вы пытаетесь сгенерировать перекрестное произведение (AB, EF) и (CD, GH) и (1,2), вы можете сделать

$ printf "%s\n" {AB,EF}{CD,GH}{1,2}
ABCD1
ABCD2
ABGH1
ABGH2
EFCD1
EFCD2
EFGH1
EFGH2

И затем, если вы пытаетесь извлечь строки в reads.txt, которые соответствуют одной из этих строк, тогда

$ grep -xFf <( printf "%s\n" {AB,EF}{CD,GH}{1,2} ) reads.txt
ABCD1
EFGH2
ABGH1
EFCD2

Другие вопросы по теме