Intereting Posts

Переименование папок на основе словаря в виде файла CSV?

Я расскажу о проблеме довольно многословной, так как я узнал, что только разговоры о конкретной подзадаче, которую я определил, приводят к пропущенным оппортунизмам … Поэтому я поставлю tl; dr вверх: есть набор папок, которые нужны для переименования в соответствии с отображением в файле CSV.

Имена папок следуют следующему шаблону:

[[:alpha:]]*[[:digit:]]*_[[:alnum:]]* 

Цифры в середине релевантны и указывают новое имя, которое должна иметь папка. Поэтому я могу запустить следующую команду sed, чтобы извлечь часть интересующего меня имени папки.

 sed 's/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/' 

Таким образом, у нас может быть папка с именем deptA100257_2bfde391c6af30fde3fca94b07bc8e7c и может вывести соответствующий идентификатор 100257 . Затем мне нужно переименовать папку в соответствии со следующей CSV:

 63;9961 63;100257 

Новое имя находится слева, идентификатор старого имени справа. Поэтому папка из приведенного выше примера должна быть переименована в 63 .

Первая очевидная проблема: несколько идентификаторов могут отображаться на одно имя. Я бы решил это, создав все «новые» папки вверх и скопировав содержимое папки.

И я мог бы взломать это, используя Python или что-то еще, возможно даже некоторые петли bash. Но что-то говорит мне, что по сути эта операция (подстановка в соответствии с файлом) не совсем необычна. Поэтому перед повторным изобретением колеса …

Я предпочитаю решения с использованием стандартных * NIX-оболочек и инструментов (особенно bash или zsh) и без «внешних» языков, таких как Perl, Ruby, Python … Но в конце я более или менее ищу «умный» подход, и если это хороший рубиновый однострочный лайнер, который выполняет свою работу, я в порядке с этим.

Я бы использовал find чтобы получить имена папок, проанализировать их с помощью sed , grep соответствующим идентификатором и копией:

 $ find . -mindepth 1 -type d | while read dir; do id=$(echo "$dir" | sed 's/\.\/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/'); new_name=$(grep -w "$id" names.csv | cut -d ';' -f 1); mkdir -p "$new_name" && mv -rv "$dir"/* "$new_name"/ && rmdir "$dir"; done 

Трюки

  • используйте mkdir -p который создаст каталог и выйдет молча, если он существует.
  • используйте grep -w в файле csv, чтобы получить только те строки, которые содержат весь идентификатор, ограниченный символами, отличными от слова. Таким образом, вы избегаете сопоставления 1123 и 123 для id 123 .

Предполагая, что ваши каталоги находятся под текущим рабочим каталогом, вот стартовая точка (так что проверьте ее перед запуском в prod):

 csvFile="/tmp/file.csv" for d in ./*; # only work with directory [[ ! -d "$d" ] && continue # extract id from directory id="$(echo "$d" | sed 's/[[:alpha:]]*\([[:digit:]]*\)_[[:alnum:]]*/\1/')" # fetch new name nid="$(awk -F';' '/'"$id"'/ {print $1}' "$csvFile")" # merge all matching dir into one mv "$d" "$nid" done 

коммунальные услуги

Вы посмотрели:

  • mmv : Массовое перемещение и переименование;
  • zmv : модуль zsh который позволяет людям делать массовое переименование.