Простой, переносимый, POSIX-совместимый способ добавления отсутствующей последней новой строки в текстовый файл:
[ -n "$(tail -c1 file)" ] && echo >> file
Этот подход не требует чтения всего файла; он может просто искать EOF и работать оттуда.
Этот подход также не требует создания временных файлов за вашей спиной (например, sed -i), поэтому жесткие ссылки не затрагиваются.
echo добавляет новую строку в файл только тогда, когда результатом подстановки команды является непустая строка. Обратите внимание, что это может произойти, только если файл не пуст и последний байт не является новой строкой.
Если последний байт файла является новой строкой, tail возвращает ее, затем подстановка команды удаляет ее; в результате получается пустая строка. Тест -n не проходит, и echo не запускается.
Если файл пуст, результатом подстановки команд также будет пустая строка, и снова echo не запускается. Это желательно, поскольку пустой файл не является недействительным текстовым файлом и не эквивалентен непустому текстовому файлу с пустой строкой.
Несмотря на то, что код в вашем вопросе вообще не работает, для решения вопроса «как я могу неразрушающим образом переместить файл, добавив числовой суффикс», что-то вроде этого может сработать:
$ cat mvr.sh
#!/usr/bin/env bash
bail() {
retcode=$1
shift
printf "%s" "$*" 1>&2
exit "$retcode"
}
[[ -f "$1" ]] || bail 1 "File '$1' not found"
if ! [[ -f "$2" ]]; then
mv "$1" "$2"
else
if [[ -d "$2" ]]; then
$0 "$1" "${2}/${1}"
exit $?
else
suffix=1
until ! [[ -f "${2}.$suffix" ]]; do
suffix=$((suffix+1))
done
mv "$1" "${2}.$suffix"
fi
fi
В действии:
$ ls
bar bar.1 bar.2 mvr.sh
$ touch foo; ls
bar bar.1 bar.2 foo mvr.sh
$./mvr.sh foo bar
$ ls
bar bar.1 bar.2 bar.3 mvr.sh
Основная суть того, как это сделать, начинается с оператора if
.
mv
.