Я работаю в баше. Я пытаюсь найти уникальные штрих-коды в строках в файле .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, потому что он хорошо работает в среде кластера Linux, которую я использую, и потому что мне удобнее писать сценарии bash, чем на других языках (я все еще новичок). Конечно, что-то в python можно заставить работать. Есть ли очевидное преимущество (скорость и т. д.), Которое я упускаю, выбирая bash?
¯_ (ツ) _ / ¯ Не знаю, просто кажется слишком сложным и тяжелым, чтобы продолжать использовать grepping / etc вместо использования более универсального языка с лучшей поддержкой строк и т. д.
Использование grep
внутри вложенного внутреннего цикла (запуск целой новой программы, чтение входного файла с самого начала и т. д.) Действительно является серьезным запахом кода. Однако это не обязательно проблема с bash, а не проблема с тем, как он применяется.
Вы просто хотите перебрать индексы массивов:
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
Не связано, но почему именно в bash?