2013-11-24 3 views
1

У меня есть много директории, которые заканчиваются «_ и 6 цифр», например:пакетного переименования папки Удаление завершающие символы

diff_gb_and_pf_2voids_158543 

Я хотел бы найти все, что папки в текущей папке, и переименуйте их путем удаления «_» и 6 цифр в конце.

До сих пор я застрял с этой командой:

find . -type d -print |grep '.*[0-9]\{6\}$' |xargs -I {} bash -c 'for i in {}; do mv "$i" ????; done;' 

Я не могу найти, как сделать последний шаг. Я бы попытался вызвать sed, но как? Кроме того, если есть более приятный способ, сообщите.

Благодаря

ответ

1

Вот один из способов, используя вашу оболочку:

for i in $(find . -mindepth 1 -type d -regextype posix-extended -regex '.*_[0-9]{6}'); do 
    mv "$i" "${i%_*}"; 
done 
+0

Это похоже на работу, спасибо. Не могли бы вы просто объяснить «$ {i% _ *}», пожалуйста? – Napseis

+0

@ Napseis: Конечно. Это замена параметров bash, которая удаляет из переменной кратчайший задний шаблон ('_ *'). Сводная таблица на странице [this] (http://www.cyberciti.biz/tips/bash-shell-parameter-substitution-2.html) может стоить того. Приветствия. – Steve

1

Здесь вы идете:

find /path -regex '.*_[0-9]\{6\}' -exec sh -c 'n="{}"; echo mv "{}" "${n%_*}"' \; 

Проверьте выход, если он выглядит хорошо, то падение echo там.

Объяснение: для каждого согласованного файла, мы запускаем подоболочку, где мы задаём имя файла в переменной n, так что мы можем использовать шаблон подстановки ${n%_*}, которая не отсекает последний _ характер и все после него до конца имени файла.

Или вот более переносимый способ, который должен работать в старых системах тоже:

find /path -name '*_[0-9][0-9][0-9][0-9][0-9][0-9]' | sed -ne 's/\(.*\)_[0-9]\{6\}$/mv "&" "\1"/p' 

Проверьте выход, если она хорошо выглядит, чем через канал, sh (добавить это: | sh)

Объяснение:

  1. команда sed получает список файлов для переименования
  2. В шаблоне мы фиксируем первую часть имени файла в \(... \)
  3. Заменим шаблон с текстом mv "&" "\1", где & замещено с рисунком, который соответствует образцу, в этом случае все исходное имя файла, и \1 замещено часть мы захватили в \(... \)
+0

первый не работает моя оболочка, но вторая. Это также работает найти. -regextype posix-extended -regex '. * _ [0-9] {6}' | sed -ne 's/\ (. * \) _ [0-9] \ {6 \} $/mv "&" "\ 1"/p' Но я не понимаю эту часть, не могли бы вы объяснить, пожалуйста ?: mv "&" "\ 1"/p – Napseis

+0

Я добавил объяснение как для 'sed', так и' $ {n% _ *} 'в первом решении. – janos

0
#!/usr/bin/env bash 
set -x 

ls -d diff* > dirlist 

while IFS='_' read field1 field2 field3 field4 field5 field6 
do 
mv -v "${field1}_${field2}_${field3}_${field4}_${field5}_${field6}" \ 
"${field1}_${field2}_${field3}_${field4}_${field5}" 
done < dirlist 
Смежные вопросы