Изменить имена файлов с помощью find и iconv - PullRequest
4 голосов
/ 29 марта 2012

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

find dir / -type f -exec mv {} $ (echo {} | iconv -f UTF8 -t 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

Ответы [ 3 ]

7 голосов
/ 29 марта 2012

Проблема с использованием $() таким образом заключается в том, что подоболочка выполняет до до выполнения команды 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##*/})"' -- {} \;

, которая разделяет часть каталога и переводит только имя файла.

1 голос
/ 29 марта 2012

Я не очень хорошо знаю iconv, но

 echo ... | iconv ....

подходит для текстовых строк, но если вы хотите использовать имя файла, конечно, вам нужно указать файл справасторона командной строки 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 {}.

ИЛИ см. Этот пост Как рекурсивно преобразовать все имена файлов в поддереве папок из UTF-8 в ASCII в Linux .

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

0 голосов
/ 30 марта 2012

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

#!/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
...