Перебирайте файлы, чтобы найти строку и отправьте файлы, содержащие эту строку, в каталоги с тем же именем в bash - PullRequest
1 голос
/ 05 октября 2019

У меня есть родительский каталог с ~ 500 файлами с каждым именем файла, начинающимся с cert, то есть cert-104.mol2, cert-105.mol2 и так далее. Каждый из этих cert файлов содержит внутри семизначный идентификатор, то есть 7988114. Всего ~ 20 уникальных семизначных идентификаторов. Я создал каталог (unique_ligands), который содержит каталог для каждого из уникальных идентификаторов, то есть каталог с именем 7988114. Внутри каждого из этих каталогов находится .mol2 файл с именем идентификатора, то есть 7988114.mol2. Подводя итог, можно сказать, что структура файла выглядит следующим образом:

/parent/unique_ligands/7988114/7988114.mol2

, где 7988114 является одним из ~ 20 уникальных идентификаторов.

В родительском каталоге с ~ 500 файлами мне нужно циклически проходить через каждыйфайл сертификата, выберите уникальный семизначный идентификатор и отправьте его в соответствующий файл identifier.mol2. Как начинающий сценарист bash, я не уверен, как к этому подойти. Я написал код, который выполняет этот процесс для одного идентификатора, 7988114:

find . -type f -name 'cert*' -exec grep -q '7988114' {} ';' -exec cp {} ./unique_ligands/7988114 ';'
cd unique_ligands/7988114
bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
mv zzz.txt 7988114.mol2
rm null
rm cert*

Как я могу превратить это в цикл, который сможет выбрать любой семизначный идентификатор? Или есть какой-то лучший способ приблизиться к этому?

edit

Чтобы уточнить, что каждая строка делает в моем примере кода выше:

find ...Эта строка просматривает все ~ 500 файлов, начиная с имени файла cert, и выбирает те файлы, содержимое которых содержит строку 7988114, и копирует их в правильный каталог 7988114. Каждый файл cert содержит ~ 100 строк молекулярных координат, информацию о зарядах и т. Д.

bash -c ... эта строка проходит по каждому из файлов cert, скопированных в каталог 7988114, идобавляет содержимое файла в новый текстовый файл zzz.txt. Каждый из файлов cert называется примерно так: cert-1.mol2, cert-2.mol2 и так далее. Для меня важно, что эта строка просматривает каждый из этих cert файлов, идущих от 1 до верхнего предела 10000, и добавляет их к zzz.txt в указанном последовательном порядке. Другие примеры, которые я обнаружил, либо не выполнялись в последовательном порядке, либо просматривались файлы cert-1*, а затем просматривались файлы cert-2*.

mv zzz.txt 7988114.mol2 По какой-то причине мне не разрешили создать7988114.mol2 файл выше, поэтому я сделал это здесь

1 Ответ

1 голос
/ 08 октября 2019

Вот один из способов, как я понял, как ответить на свой вопрос выше (с помощью и вдохновением от пользователя shellter выше - спасибо!):

ls -l | grep ^d | awk '{print $9}' > list_of_ligands.txt
mv list_of_ligands.txt ..

cd ..

while read NAME
do
        echo "$NAME"
        grep -l "$NAME" cert* | while read -r filename ; do
        cp $filename unique_ligands/$NAME
        cd unique_ligands/$NAME
        bash -c 'cat $(for((i=0;i<10000;i++)); do echo -n "cert-${i}.mol2 "; done) > zzz.txt 2> ./null'
        mv zzz.txt $NAME.mol2
        rm null
        rm cert*
        cd ../..
done
done < list_of_ligands.txt

Как я уже упоминал в своем первоначальном вопросе, у меня былоранее создан каталог для каждого 7-значного идентификатора. Строка ls -l выбирает имя каталога и создает вертикальный список имен каталогов (который, опять же, представляет собой просто каждый 7-значный идентификатор, который у меня есть).

Два цикла while повторяются через каждые 7номер идентификатора у меня есть, и выполните команды, которые я упомянул в моем первоначальном вопросе.

...