Цикл для итерации по дереву каталогов, извлекая результаты из файлов с одинаковыми именами

Цикл для итерации по дереву каталогов, извлекая результаты из файлов с одинаковыми именами

У меня есть ряд каталогов, все list.txtв одном формате, и я хочу поместить результаты в один файл. Я хочу написать скрипт, который будет итеративно проходить по каждому дереву каталогов, извлекать определенный столбец из файла list.txtбез окружающего текста с помощью конвейера grep/awk ниже и записывать выходные данные каждого из них в тот же файл.

    grep 'bar[0-9]' file.txt | awk '{print $1}'

Я попытался сделать следующее, но не уверен, где именно мои циклы в скрипте идут не так.

#!/bin/bash
##Extract ligands from toplist and concatenate to file
for i in /home/ubuntu/Project/working/library_*/Results/list.txt
do
    grep 'bar[0-9]' i | awk '{print $1}' | cat ../output.txt i
done

Дерево каталогов выглядит следующим образом:

.
├── library_1-200
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_201-400
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_401-600
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
└── library_601-800
    ├── Results
    │   ├── complex
    │   ├── sorted.txt
    │   └── list.txt
    ├── files
    │   ├── output
    │   └── txt
    └── summary.txt

Образец list.txt, где я просто хочу, чтобы Nameзначения были введеныoutput.txt

Name    Score
bar65    -7.8 
bar74    -7.5 
bar14    -7.5 
bar43    -7.4 
bar94    -7.4 
bar16    -7.4 
bar12    -7.3 
bar25    -7.3 
bar65    -7.3 
bar76    -7.3 
bar24    -7.3 
bar13    -7.3 
bar58    -7.2 
bar68    -7.2 
bar28    -7.2 

Решением было поместить «$i» туда, где раньше был только i, и изменить на| cat >> ../output.txt

решение1

Вы используете i, вместо этого используйте $iв команде grep.

И если вы сказали, что хотите поместить их все в один ряд, то последняя команда должна быть такой:

cat >> /home/ubuntu/Project/working/output.txt

Или просто:

>> /home/ubuntu/Project/working/output.txt

решение2

Помимо исправления некоторых небольших опечаток в исходном коде (использование "$i"вместо iи перенаправление вывода в выходной файл вместо попытки вывести его содержимое), если у вас не так много тысяч таких list.txtфайлов:

awk '/^bar[0-9]/ { print $1 }' /home/ubuntu/Project/working/library_*/Results/list.txt >output.txt

Это используется awkдля извлечения первого столбца всех строк, начинающихся со строки, barза которой следует цифра. Это делается для всех файлов, соответствующих шаблону /home/ubuntu/Project/working/library_*/Results/list.txt. Извлеченные данные перенаправляются в output.txt.

Цикл становится необходимым, когда шаблон подстановки имен файлов /home/ubuntu/Project/working/library_*/Results/list.txtрасширяется до слишком большого количества имен:

for pathname in /home/ubuntu/Project/working/library_*/Results/list.txt; do
    awk '/^bar/ { print $1 }' "$pathname"
done >output.txt

Обратите внимание, что более эффективно перенаправить выводпетлячем каждого отдельного awkзвонка. Также обратите внимание, что awkлегко выполняет работу по grepобнаружению нужных линий, и это catне нужно.

Если вам нужен первый столбец из всех строк, кроме первой (как в вашем примере данных), вы можете изменить условие в awkкоде с /^bar[0-9]/на FNR > 1.

Связанный контент