Рекурсивно переименуйте почтовые файлы от .txt до .eml

/etc/localtime управляет системным часовым поясом. Это - просто символьная ссылка на один из файлов часового пояса в /usr/share/zoneinfo.

ln -sf /usr/share/zoneinfo/your/zone /etc/localtime
2
11.06.2012, 20:38
4 ответа

Ваше решение обычно в порядке, но оно повредится на новых строках. Вот немного больше устойчивого bash4 + решение:

shopt -s globstar nullglob
for file in **/*.txt; do
    mv "$file" "${file%.*}.eml"
done
5
27.01.2020, 21:55

Я думаю, что необходимо согласиться с

find "$d" -name \*.txt -exec rename .txt .eml {} \;

или даже

for f in *.txt; do rename .txt .eml "$f"; done

если все файлы находятся в том же каталоге.

1
27.01.2020, 21:55
  • 1
    система, я иду, не имеет, "переименовывают". –  Robottinosino 11.06.2012, 21:25

Да, Ваша команда будет работать, предполагая, что Вы используете bash или оболочка с подобным синтаксисом. В будущем при рассмотрении большой команды как это помните, что можно использовать echo предварительно просматривать получающиеся командные строки. Т.е. Вы могли поместить echo перед mv, выполните конвейер и посмотрите то, чем будут команды. Если они смотрят хорошо, удаляют echo и выполненный команда для реального.

0
27.01.2020, 21:55

В 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' {} \;
0
27.01.2020, 21:55

Теги

Похожие вопросы