/etc/localtime
управляет системным часовым поясом. Это - просто символьная ссылка на один из файлов часового пояса в /usr/share/zoneinfo
.
ln -sf /usr/share/zoneinfo/your/zone /etc/localtime
Ваше решение обычно в порядке, но оно повредится на новых строках. Вот немного больше устойчивого bash4 + решение:
shopt -s globstar nullglob
for file in **/*.txt; do
mv "$file" "${file%.*}.eml"
done
Я думаю, что необходимо согласиться с
find "$d" -name \*.txt -exec rename .txt .eml {} \;
или даже
for f in *.txt; do rename .txt .eml "$f"; done
если все файлы находятся в том же каталоге.
Да, Ваша команда будет работать, предполагая, что Вы используете bash
или оболочка с подобным синтаксисом. В будущем при рассмотрении большой команды как это помните, что можно использовать echo
предварительно просматривать получающиеся командные строки. Т.е. Вы могли поместить echo
перед mv
, выполните конвейер и посмотрите то, чем будут команды. Если они смотрят хорошо, удаляют echo
и выполненный команда для реального.
В zsh, zmv
делает это легким. Поместить autoload -U zmv
в Вашем ~/.zshrc
, затем используйте один из нескольких способов указать текст замены для **/*.txt
который соответствует файлам расширению txt
в текущем каталоге и подкаталогах:
zmv '**/*.txt' '$f:r.eml'
zmv '**/*.txt' '${f%.*}.eml'
zmv '(**/)(*).txt' '$1$2.eml'
zmv -w '**/*.txt' '$1$2.eml'
Если у Вас нет zsh, но у Вас есть удар ≥4 или ksh93, можно использовать **
пересекать подкаталоги рекурсивно и затем цикл по соответствиям. Необходимо будет активироваться **
шаблон шарика сначала с shopt -s globstar
в ударе (вставляет его Ваш ~/.bashrc
) или set -o globstar
в ksh (вставляет его Ваш ~/.kshrc
). Это также работает в zsh (никакая предшествующая необходимая установка).
for f in **/*.txt; do mv -- "$f" "${f%.*}.eml"; done
Обратите внимание, что это переименовывает все файлы, не только регулярные файлы. Если у Вас есть каталоги или другие нерегулярные файлы, и Вы хотите оставить их нетронутыми:
zmv -Q '**/*.txt(.)' '$f:r.eml'
for f in **/*.txt; do [[ -f $f ]] && mv -- "$f" "${f%.*}.eml"; done
Без функции оболочки вне POSIX необходимо будет вызвать find
пересекать подкаталоги. Ваше решение является хрупким, потому что оно повреждается на файлах, содержащих обратные косые черты, запаздывающий пробел или новые строки. Можно зафиксировать запаздывающий пробел и проблему обратных косых черт с while IFS= read -r f; do …
но передавая вывод по каналу find
по сути повреждения на новых строках. Использовать -exec
вместо этого. На Linux можно использовать rename
утилита (какой бы ни Ваше распределение несет). На Debian, Ubuntu и производных:
rename 's/\.txt$/.eml/' **/*.txt
find . -name '*.txt' -type f -exec rename 's/\.txt$/.eml/' {} +
На других дистрибутивах пока ни одни из имен файлов не содержат .txt
в середине (потому что rename
заменяет первым вхождением исходной строки):
rename .txt .eml **/*.txt
find . -name '*.txt' -type f -exec rename .txt .eml {} +
Только с функциями POSIX повсюду, вызовите оболочку для выполнения преобразования на имени.
find . -name '*.txt' -type f -exec sh -c 'for f; do mv "$f" "${f%.*}.eml"; done' _ {} +
Если Ваш find
слишком старо для поддержки -exec … +
, необходимо будет вызвать одну оболочку на файл, который делает для более простого но более медленного кода.
find . -name '*.txt' -type f -exec sh -c 'mv "$0" "${0%.*}.eml"; done' {} \;