Выходной файл пуст для скрипта Bash, который "находит" с помощью GNU sed (gsed)

У меня много файлов, каждый в каталоге. Мой скрипт должен:

  • Найти строку в файле. Допустим, файл называется "результаты", а строка "средняя".

  • Затем добавьте все остальное в строке строки в другой файл с именем "allResults". После запуска скрипта файл "allResults" должен содержать столько строк, сколько имеется файлов "результатов", например

allResults.txt (что я хочу):

Everything on the same line as the string, "average" in directory1/results
Everything on the same line as the string, "average" in directory2/results
Everything on the same line as the string, "average" in directory3/results
...
Everything on the same line as the string, "average" in directory-i/results

Мой сценарий может найти то, что мне нужно. Я проверил, выполнив "cat" для "allResults.txt" во время работы скрипта и "ls -l" в родительском каталоге "allResults.txt". То есть, я вижу вывод "find" на моем экране, и размер "allResults.txt" ненадолго увеличивается, а затем возвращается к 0. Проблема заключается в том, что "allResults.txt" становится пустым после завершения сценария. Таким образом, результаты поиска не добавляются и не добавляются в allResults.txt. Они перезаписываются. Вот мой сценарий (я использую "gsed", GNU sed, потому что я пользователь Mac OSX Sierra):

#!/bin/bash

# Loop over all directories, find.
let allsteps=100000
for ((step=0; step <= allsteps; step++)); do
    i=$((step));

    findme="average"
    find ${i}/experiment-1/results.dat -type f -exec gsed -n -i "s/${findme}//p" {} \; >> allResults.txt
done 

Обратите внимание, что я использовал ">>" в моем примере здесь, потому что я прочитал, что он добавляет (что я и хочу - список всех строк, соответствующих моему "find" из всех файлов), тогда как ">" перезаписывается. Однако в обоих случаях (когда я использую ">" или ">>"), я получаю пустое allResults.txt файл.

1 ответ

Решение

Стандартное поведение grep - распечатывать совпадающие строки. Использование sed - это излишне.

Вам также не нужен явный цикл. Действительно, избыточные циклы - это обычная практика, которую программисты стремятся импортировать из других языков, где циклы распространены. Большинство команд и конструкций оболочки принимают несколько имен файлов.

grep average */experiment-1/results.dat > allResults.txt

Что приятно, так это то, что выходной файл открывается только один раз и записывается одним махом.

Если у вас действительно есть сотни тысяч файлов для обработки, вы можете столкнуться с ограничением длины командной строки. Если это произойдет, вы можете переключиться на find вызов, который не вызовет grep с большим количеством файлов одновременно.

find . -name results.dat -exec grep average {} + > allResults.txt
Другие вопросы по тегам