UNIX команда для перемещения нескольких файлов в несколько подкаталогов?
Я работаю в окне X11 на машине MAC OS X. Теперь у меня есть сотни файлов в одном каталоге, каждое имя файла содержит подстроку, такую как "1970", "1971",..., "2014" и т. Д., Указывающие, что файл предназначен для этого года. Сейчас я только что создал подкаталоги с именами "1970", "1971", ..., "2014".
Что такое однострочная команда UNIX, которая переместит все файлы в подкаталоги, соответствующие их годам?
1 ответ
Если подкаталоги с названием года находятся в единственном каталоге, который в настоящее время содержит все файлы, то вы сможете использовать что-то вроде этого, предполагая, что текущий каталог является этим единственным каталогом:
shopt -s nullglob
for year in {1970..2014}
do
mv *?${year}* $year
mv *${year}?* $year
done
Глобализация требует, чтобы по крайней мере еще один символ в имени был перемещен, а не только год, до или после года, чтобы предотвратить попытку перемещения 1970
в себя (который потерпит неудачу). Вам нужно два mv
команды для предотвращения a-1970-b
от совпадения обоих выражений глобуса (что приведет к сбою второго, поскольку файл уже был бы удален). Подобное использование глобинга сохраняет правильные пробелы и т. Д. В именах файлов. (Использование подстановки команд и т. Д. Не подходит.)
shopt
Команда означает, что если для данного глоба нет файлов, в выводе ничего не будет. Это сгенерирует ошибку использования из mv
(неприятность), но в остальном безвреден. Вы можете решить фильтровать такие сообщения об ошибках, если вы действительно хотите; Вы, вероятно, не хотите отправлять все сообщения об ошибках /dev/null
, хоть.
Так как вы на Mac, у вас нет GNU mv
с очень полезным -t target
вариант.
Вы сказали, что вам нужна однострочная команда; замените каждый символ новой строки, кроме одного после do
с точкой с запятой; заменить символ новой строки после do
с пробелом.
Если вы знаете, что год никогда не находится в начале или конце имени файла, вы можете использовать один mv *?${year}?* $year
команда.