Мне было удивительно сложно использовать инструменты, которые я обычно использовал ( sed, tail -c 1 file.txt | read || echo >> file.txt ), но элегантное решение существует с использованием стандартных команд оболочки:
tail
readВыводит последний байт файлаechoЧитает строку в переменную. Если указанная переменная указана, это не-op, но если EOF встречается перед новой строкой, выходит с кодом 1.file.txtВыполняется только в том случае, если чтение не выполняется (т. Е. Если последний символ не был символом новой строки) и добавляет новую строку вfind
Найти -not -path "./.git/*" -type f -exec sh -c "grep -Iq. {} && (tail -c 1 {} | читать || echo >> {})" ; файлы, которые мы хотим изменить, вы можете использовать -not -path:
.git/
-type fисключает-exec sh -c "...", с которыми мы не хотимgrep -Iq .ограничивает поиск файлов.требуется объединить вместе команды, которые включают в себя каналы{}ищет что-либо (.), так что нет-op, но выходит с кодом 1, если файл двоичныйfindотмечает позицию, в которуюfindбудет вставлять имя файла
Я бы посоветовал проверить список файлов перед запуском команды. Сделайте это путем замены echo >> {}с echo {}:
find -not -path "./.git/*" -type f -exec sh -c "grep -Iq . {} && (tail -c 1 {} | read || echo {})" ;