Форум программистов, компьютерный форум, киберфорум
Shell, Bash
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.88/8: Рейтинг темы: голосов - 8, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35

Вывод отчетов для вложенных директорий на BASH

23.02.2017, 13:44. Показов 1674. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте. Возникла следующая задача. Имеется такая структура директорий:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/head/
 
   dir_one/
     subDir_one/
        task/
           log.txt
        test_task/
           log.txt
 
      subDir_two/
        task/
           log.txt
        test_task/
           log.txt
    
      subDir_three/
      ...
      subDir_N
 
   dir_two/
      ...
   ...
   dir_N/
      ...
Листьями (если так можно выразиться) всех поддиректорий (количество которых в общем случае неизвестно), как видно, являются файлы log.txt. Нужно:
1) Для каждого хранящегося в каталоге test_task (и только) log.txt проверить, есть ли там слово "fail" и для каждой директории в файл вывести отчет в следующем виде:
NOT: dir_one/subDir_one
FOUND: dir_one/subDir_two
NOT: dir_one/subDir_three

2) Если слово "fail" для какого-либо каталога 'dir_N/subDir_M' есть, то в нем необходимо сформировать файл report.txt и занести туда информацию, вида "test_task/log.txt(line=23): "file" found".

Мои попытки.
Первое, что хочу сказать - пытаюсь писать на bash впервые. Решил, что на нем будет легче всего реализовать эти манипуляции, так как обнаружил чудесную команду grep. Однако, как только я попытался сделать реализацию, столкнулся с рядом недопониманий. Первое, пишу я такую команду: grep -rn -w fail head/ >out. Получаю файл строк, состоящий из названий файлов и полным их путем, а формат вывода должен быть иной. Поэтому первая проблема - как можно получить нужный формат вывода, указанный в пункте 1? По пункту 2 почти аналогичная ситуация - как создать файл report.txt именно в этой директории и именно с таким содержанием, если, по сути, остановить рекурсивное выполнение grep невозможно, если, допустим, в каком-то файле мы нашли соответствующее слово?

Заранее спасибо!
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.02.2017, 13:44
Ответы с готовыми решениями:

Вывод в файл списка всех вложенных директорий заданного каталога
Подсобите!! Пожалуйста!! Разработать пакетный файл для вывода в файл списка всех вложенных директорий заданного каталога. Каталог...

Отображение вложенных директорий без вложенных файлов (shlwapi.dll)
Здравствуйте. Вопрос: существует ли функция в shlwapi (или других библиотеках), позволяющая по имени (или идентификатору) какой-либо...

Разработать командный файл для вывода в файл списка всех вложенных директорий заданного каталога
Здравствуйте,помогите пожалуйста разработать файл для вывода в файл списка всех вложенных директорий заданного каталога (директория...

15
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
23.02.2017, 17:46
Попробую написать первую часть на zsh

Bash
1
2
3
4
5
6
7
8
9
10
#!/usr/bin/zsh
 
for f in **/test_task/log.txt; do
    if grep -q fail $f; then
        print -n 'FOUND: '
    else
        print -n 'NOT: '
    fi
    print -- ${f:h:h}
done
** ― рекурсивный глоб, print ― встроенная функция печати. В zsh при подстановки значений переменных пробелы не превращаются в разделители, поэтому скрипт будет работать и для имён с пробелами, хотя я пишу $f без кавычек.

Вторую часть тоже могу попробовать, но поясните, откуда берётся "file" found.
1
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
23.02.2017, 18:56  [ТС]
Большое спасибо за Ваше решение. Попробую реализовать его.
Прошу прощения. Во второй части " 'fail' found". То есть в подкаталоге subDir_N должен создаться файл report.txt в случае, если в subDir_N/test_task/log.txt нашелся хотя бы один 'fail'. А содержимое этого файла будут строки формата "test_task/log.txt(line=23): "fail" found;
test_task/log.txt(line=54): "file" found;
...
test_task/log.txt(line=N): "file" found."
То есть где именно и в каких строчках log.txt нашелся fail.
0
4528 / 3522 / 358
Регистрация: 12.03.2013
Сообщений: 6,038
24.02.2017, 02:21
Попробуйте:
Bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#!/usr/bin/zsh
 
root_dir=${1:-$PWD}
 
for dir in $root_dir/**/test_task(/); do
    report=${dir:h}/report.txt
    rm -f $report
    lines=${(f)"$(awk '/fail/{printf "test_task/log.txt(line=%d): "fail" found\n", NR;}' < $dir/log.txt)"}
    if [[ ${#lines} == 0 ]]; then
        print "NOT: ${dir:h}"
    else
        print "FOUND: ${dir:h}"
        print -l -- $lines > $report
    fi
done
Если у вас стоит zsh, достаточно сохранить код в файл report и сделать его исполняемым:
Bash
1
chmod +x report
1: скрипт для zsh
3: в качестве корневой директории для поиска используется первый аргумент команды, а если его нет ― текущая директория
5: в цикле перебираются все поддиректории с именем test_task вне зависимости от уровня вложенности
6: файл отчёта
7: если файл (старого) отчёта существует, его надо удалить
8: awk ищет в файле-логе строки со словом fail и формирует строки по образцу; строки собираются в массив lines
9-13: если массив пустой, сообщается что всё нормально; в противном случае сообщается, что не всё нормально, и строки записываются в файл отчёта

Не по теме:

Я просто недавно прочитал книжку про zsh, и подумалось, что было бы забавно написать с рекурсивным глоббингом. Ну и zsh пофорсить заодно.

1
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 11:17
Это задание выполняется 1-3 командами. Если приведете пример log.txt
0
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 11:27  [ТС]
Лог в общем случае имеет около 4000 строчек. Пример:
Bash
1
2
3
4
5
6
xxx yyy: successes
abc dsa: successes
zzz asd: fail
...
fail of elapsed time: 1s (need 0.8s) 
etc..
Примерно в таком стиле.
0
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 13:54
Лучший ответ Сообщение было отмечено wator как решение

Решение

Bash
1
2
3
4
5
6
7
8
9
10
11
12
cd /head/
for subdir in */*/ ; do
    cd "${subdir}"
    if grep -sHn 'fail'  test_task/log.txt > report.txt; then
       echo FOUND: "$subdir"
       sed -i 's/:\([0-9]*\):.*/(line=\1): «fail» found/' report.txt
    else
       echo NOT: "$subdir"
       rm -f report.txt
    fi
    cd -
done > /head/main_report.txt
1
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 19:26  [ТС]
Большое спасибо. Все получается, только возникло пару проблем-вопросов:
1) Репорт выходит в виде
Bash
1
2
3
4
5
OK: xxxx
/home/user/head
OK: yyyyy
/home/user/head
...
Как можно эту строчку "/home/user/head" ликвидировать?

2) Как можно вывести сообщение, стоящее после слова fail в report.txt ? То есть не просто строчку и что найден "fail", а "fail found in "FAIL: out of memory" ", где "out of memory" строка, стоящая после найденного слова 'fail' ?

Добавлено через 1 час 51 минуту
То есть пример. До парсинга строки имеем строку в report.txt следующую:
XML
1
test_task/log.txt:547: test started bla-bla FAIL: out of memory
Сейчас эта строка преобразовывается в
XML
1
test_task/log.txt(line=547): "fail" found
Возможно ли, чтобы она преобразовывалась в такую ?
XML
1
test_task/log.txt(line=547): "fail" found in str "FAIL: out of memory"
0
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 20:12
1.
Bash
11
    cd - >/dev/null
2.
Bash
6
        sed -i 's/:\([0-9]*\):/(line=\1): "fail" found in str: /' report.txt
0
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 20:24  [ТС]
Marinero, Тогда будет выводится так:
XML
1
test_task/log.txt(line=547): "fail" found in str test started bla-bla "FAIL: out of memory"
Возможно без "test started bla-bla"?
0
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 20:31
Bash
1
sed -i 's/:\([0-9]*\): .*FAIL/(line=\1): "fail" found in str: FAIL/' report.txt
1
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 20:39  [ТС]
Marinero, Не получилось, и (line=N) теперь тоже нет.
0
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 20:57
Какие данные даете, на таких и строится команда
Code
1
2
3
4
…$: echo 'test_task/log.txt:547: test started bla-bla FAIL: out of memory' | 
sed 's/:\([0-9]*\): .*FAIL/(line=\1): "fail" found in str: FAIL/'
test_task/log.txt(line=547): "fail" found in str: FAIL: out of memory
…$:
1
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 21:09  [ТС]
Marinero, Нашел ошибку. Из-за отсутствия пробела не работало . Большое Вам спасибо!
Могу я еще задать вопрос в этой теме по поводу поиска максимального значения в файле из всех, которые стоят после определенного слова ?
0
Эксперт NIX
 Аватар для Marinero
2796 / 2039 / 682
Регистрация: 02.03.2015
Сообщений: 6,509
24.02.2017, 21:31
Цитата Сообщение от wator Посмотреть сообщение
Могу я еще задать вопрос
Нет. Один вопрос — одна тема
0
0 / 0 / 0
Регистрация: 02.04.2014
Сообщений: 35
24.02.2017, 21:34  [ТС]
Понял. Благодарю всех еще раз!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
24.02.2017, 21:34
Помогаю со студенческими работами здесь

Создать html-страницу с деревом вложенных директорий
Доброе время суток подскажите есть код написанный не мной отел бы разобраться как он работает &lt;!DOCTYPE HTML&gt; &lt;html&gt; ...

Вложенные каталоги: как получить изображения из вложенных директорий?
Добрый день. Я получаю все изображения из заданной директории: if(SetCurrentDirectoryA(path)) { ...

Очистить содержимое вложенных директорий сохранив структуру каталогов
Как можно очистить содержимое вложенных директорий сохранив при этому структуру каталогов?

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

Вывод изображений из директорий
Добрый день! У нас есть директория,в которую загружаются изображения(различных форматов: jpg,gif,png): /uploads Подскажите как вывести...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
[В процессе разработки] SDL3 для Web (WebAssembly): Сборка библиотек SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия SDL 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual. . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru