Выходной файл пуст для скрипта 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