Как я могу конвертировать имена папок из одного формата даты в другой?
У меня есть большое количество папок, названных как даты:
10 Aug 2010 15 Sep 2010 20 Jun 2010 25 Jul 2010 6 Nov 2010
10 Sep 2010 16 Aug 2010 20 Mar 2010 26 Aug 2010 6 Oct 2010
11 Apr 2010 16 Jun 2010 21 Jun 2010 28 Aug 2010 7 Apr 2010
12 Aug 2010 16 Oct 2010 21 Mar 2010 28 Feb 2010 7 Aug 2010
13 May 2010 17 Apr 2010 22 Feb 2010 28 Jun 2010 7 Jun 2010
14 Aug 2010 17 Aug 2010 23 Jul 2010 28 Mar 2010 8 Apr 2010
14 Jun 2010 18 Aug 2010 24 Jul 2010 29 Mar 2010 8 Aug 2010
15 Aug 2010 19 Aug 2010 24 Nov 2010 30 Aug 2010 8 Jul 2010
15 Jul 2010 4 Apr 2010 25 Apr 2010 6 May 2010 8 Sep 2010
Я хочу изменить формат даты на этот:
2010-04-04 2010-05-03
2010-06-06 2010-07-02
2010-07-05 2010-09-01
2010-09-04 2010-09-05
2010-11-01
Как я могу пакетно переименовать много папок из DD MMM YYYY
в YYYY-MM-DD
?
5 ответов
К моему удивлению, похоже, наш старый друг prename
(ака rename
в некоторых системах) это можно сделать с небольшим скандалом:
$ prename -vn -- '
BEGIN{use Time::Piece};
s/\d+ \w+ \d+/Time::Piece->strptime($&, "%d %b %Y")->strftime("%Y-%m-%d")/e
' *
10 Aug 2010 renamed as 2010-08-10
8 Sep 2010 renamed as 2010-09-08
В качестве альтернативы, используя GNU date
dirs=( ?\ ???\ ???? ??\ ???\ ???? ) # matches D MMM YYYY and DD MMM YYYY
for d in "${dirs[@]}"; do mv -v -- "$d" "$(date '+%Y-%m-%d' -d "$d")"; done
Тестирование с echo
(эквивалентно предварительному имени -n
флаг):
$ for d in "${dirs[@]}"; do echo mv -v -- "$d" "$(date '+%Y-%m-%d' -d "$d")"; done
mv -v -- 8 Sep 2010 2010-09-08
mv -v -- 10 Aug 2010 2010-08-10
Обратите внимание, что разбор дат может зависеть от локали.
GNU date
Команда очень хороша для преобразования между различными форматами даты. Например:
$ date -d '17 Aug 2010' +%F
2010-08-17
Имея это в виду, что если в вашей целевой директории есть только те подкаталоги, которые вы хотите переименовать, вы можете просто сделать:
for d in *; do mv "$d" "$(date -d "$d" +%F)"; done
Если вы хотите указать только каталоги, используйте:
for dir in */; do d=${dir%%/}; mv "$d" "$(date -d "$d" +%F)"; done
И сопоставлять только каталоги, имя которых начинается с цифры:
for dir in [0-9]*/; do d=${dir%%/}; mv "$d" "$(date -d "$d" +%F)"; done
Вот скрипт Python, который может сделать переименование, используя datetime
модуль:
#!/usr/bin/env python
from datetime import datetime
import os
import os.path
import sys
def main(target):
dir_path = os.path.abspath(target)
for i in os.listdir(target):
old_name = os.path.join(dir_path, i)
d = datetime.strptime(i, '%d %b %Y').strftime('%Y-%m-%d')
new_name = os.path.join(dir_path, d)
os.rename(old_name, new_name)
if __name__ == '__main__':
main(sys.argv[1])
Давайте назовем сценарий rename.py
, Чтобы использовать скрипт, сначала сделайте его исполняемым, запустив chmod +x rename.py
а затем работает ./rename.py parent_dir
где parent_dir
является родительским каталогом, содержащим все каталоги, имена которых вы хотите изменить.
Вот скрипт Ruby, который делает то же самое. Поместите это в каталог, где находятся все эти каталоги.
#!/usr/bin/env ruby
require 'time'
Dir.glob('*').select do |f|
if File.directory? f
time = Time.parse(f.to_s)
File.rename(f, time.strftime("%Y-%m-%d"))
end
end
использование chmod +x rename.rb
а также ./rename.rb
переименовать каталоги
Если вы хотите хорошее решение с графическим интерфейсом, попробуйте Pyrenamer легко и очень настраиваемый