2012-03-29 3 views
4

Я попытался изменить имена файлов, используя следующий скрипт:Изменить имена файлов с находкой и Iconv

найти реж/-типа е -exec мв {} $ (эхо {} | Iconv -f -t UTF8 ASCII// TRANSLIT) \;

Почему это не работает? Я имею в виду, когда у меня есть файл с символом типа '±', он должен преобразовать его в 'a'.

$ echo ążźćó | iconv -f UTF8 -t ASCII//TRANSLIT 
azzco 

Почему это не работает в find -exec?

$ find dir/ -type f -exec mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT) \; 
mv: `dir/zią' and `dir/zią' are the same file 

я получаю тот же результат с помощью xargs:

$ find dir/ -type f | xargs -I{} echo {} | iconv -f UTF8 -t ASCII//TRANSLIT 
dir/zia 

но:

$ find dir/ -type f | xargs -I{} mv {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT) 
mv: `dir/zią' and `dir/zią' are the same file 

ответ

6

Проблема с использованием $() таким образом, что подоболочка выполняет перед для выполнения команды find, а не как часть -exec. Вы можете это сделать, но вам нужно вызвать bash. Что-то вроде:

find dir/ -type f -exec bash -c 'mv "$1" "$(iconv -f UTF8 -t ASCII//TRANSLIT <<< $1)"' -- {} \; 

Имейте в виду, что это будет также транслит любые специальные символы в именах каталогов, а также, что может привести к сбою mv. Если вы хотите, чтобы транслит имя файла, то вы можете:

find dir/ -type f -exec bash -c 'mv "$1" "${1%/*}/$(iconv -f UTF8 -t ASCII//TRANSLIT <<< ${1##*/})"' -- {} \; 

, которые расщепляются часть каталога выключен и только translits имя файла.

+0

это именно то, чего мне не хватало. Большое спасибо! – wisent

+0

$ (iconv -f UTF8 -t ASCII // TRANSLIT <<< $ 1) - остерегайтесь $ 1 здесь не цитируется, и несколько пробелов будут разделены! ех. "{пробел} {пробел} b" станет "{пробелом} b". чтобы обойти это, вы можете использовать echo -n с трубой вместо herestring – user2847643

1

Я не знаю Iconv, что хорошо, но

echo ... | iconv .... 

отлично для текстовых строк, но если вы хотите, чтобы вы использовали имя файла, конечно, u необходимо указать файл в правой части командной строки iconv, т. е.

ls *.files | xargs -I{} iconv -f UTF8 -t ASCII//TRANSLIT {} 

правый?

Что касается перемещения (mv) файла, убедитесь, что исходное имя файла отличается от имени файла назначения. От вас не ясно, что вы хотите, чтобы имя целевого файла было. Если iconv может изменять файлы на месте И вы не хотите сохранять оригинал, тогда я ожидал бы, что приведенные выше xargs должны решить вашу проблему.

Или вы говорите, что фактические имена файлов содержат символы, которые вы хотите обработать, с помощью iconv. Это может помочь отредактировать ваше сообщение, чтобы включить образцы имен файлов, до и после обработки iconv. Что-то вроде этого?

find dir/ -type f -exec mv {} $(echo {}.fix | iconv -f UTF8 -t ASCII//TRANSLIT) \; 

Для имен файлов, которые не модифицируются с помощью iconv, вы должны иметь способ сделать имя отдельно от исходного файла. Таким образом, за этим последует шаг /bin/rm {}.

ИЛИ см. Это сообщение How to recursively convert all filenames in folder subtree from UTF-8 to ASCII in Linux.

Надеюсь, это поможет.

+0

@wisent: Я думаю, что я закончил правку мой пост. Удачи. – shellter

+0

На самом деле я был вдохновлен этим сообщением :) Я просто хотел сделать это для обучения цели. @FatalError предоставил точное решение для моей проблемы, но спасибо за вклад. – wisent

0

Это также должно работать:

#!/bin/bash 
if [ "$1" = "DO" ] ; then 
if [ "$2" != "$3" ]; then 
    mv "$2" "$3"; 
fi 
else 
find dir/ -type f -exec "bash" $0 "DO" {} $(echo {} | iconv -f UTF8 -t ASCII//TRANSLIT) \; 
fi 
Смежные вопросы