Переименование файлов и папок с помощью специальных символов

Борьба с этим и Google, кажется, не дает мне решение, которое работает.

У меня есть папка с именем...

file å?? name.txt

Например, чтобы избежать проблем, я хочу переименовать его, но я пытаюсь понять, как это сделать. Я пытался использовать ' ' и я также пытался использовать \ перед каждым специальным символом, например 'file \å\?\? name \(2008\).txt' но я просто получаю следующую ошибку...

-bash: cd: file \å\?\? name \(2008\).txt : No such file or directory

Это неправильное использование \ или мне нужен альтернативный подход?

Спасибо

3 ответа

Решение

Не-ASCII символы не проблема, ваша оболочка может справиться å на отлично. Проблема в том, что ваш файл на самом деле не назван å??, Если бы, rm 'å??' или даже rm å?? работал бы.

Вы предполагаете, что это å?? потому что это то, что ls показывает, и это разумное предположение, но ls покажет разные вещи как ?, Например:

$ mkdir "file å"\?\?" name.txt" "file å"$'\n'$'\n'" name.txt" "file å"$'\t'$'\t'" name.txt" "file å"$'\r'$'\r'" name.txt" "file å"$'\b'$'\b'" name.txt" "file å"$'\v'$'\v'" name.txt"

$ ls -l
total 24K
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:01 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt
drwxr-xr-x 2 terdon users 4.0K Nov  8 13:02 file å?? name.txt

Как вы можете видеть выше, новые строки, вкладки, возврат каретки, колокольчики и вертикальные вкладки (среди прочих) отображаются как ?, Только первый файл / каталог из созданных выше на самом деле имеет ? в его названии. Мы можем подтвердить это ls -b:

$ ls -lb
total 24
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å??\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\b\b\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\t\t\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:01 file\ å\n\n\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\v\v\ name.txt
drwxr-xr-x 2 terdon users 4096 Nov  8 13:02 file\ å\r\r\ name.txt

Итак, вы можете запустить ls -b чтобы получить правильное имя файла, а затем использовать цитирование ANSI C для его переименования:

mv å$'\r'$'\r' newname

Кроме того, вы можете использовать glob для сопоставления всех файлов / каталогов, чье имя начинается с file å (примечание: это будет работать, только если у вас есть):

mv "file å*" newname

Или переименуйте все файлы / каталоги, имя которых содержит не алфавитно-цифровые символы (опять же, полезно только для случаев, когда у вас есть один такой случай):

shopt -s extglob  ## turn on extended globbing
mv !(*([[:graph:]])) newname

Странный !(*([[:graph:]])) нуждается в объяснении. extglob позволяет расширенную глобализацию, которая позволяет нам использовать !(foo) соответствовать "не фу". [[:graph:]] класс символов соответствует всем печатным символам (не символам табуляции, символам новой строки и т. д.) !(*([[:graph:]])) будет сопоставлять все имена файлов / каталогов с непечатными символами.

Если вам нужно иметь дело с более чем одним таким случаем, используйте цикл. Что-то вроде:

for dir in !(*([[:graph:]])); do 
     mv "$dir" "${dir//[^[:graph:]]/_}"; 
done

${dir//[^[:graph:]]/_} имя каталога, в котором все непечатаемые символы заменены на _, Проблема с этим подходом заключается в том, что у вас могут быть разные исходные каталоги, которые в конечном итоге будут иметь одинаковые имена (например, foo\n а также foo\t оба станут foo_). Если это проблема, просто переименуйте, используя счетчик:

a=0; for dir in !(*([[:graph:]])); do 
    ((a++)); 
     mv "$dir" "${dir//[^[:graph:]]/_}$a"
done

Это приведет к:

drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt1
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt2
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt3
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å??_name.txt4
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt5
drwxr-xr-x 2 terdon users 4096 Nov  8 13:08 file_å___name.txt6

Вы явно пытались экранировать и цитировать, вы также можете использовать подстановочные знаки с назойливыми именами файлов, например,

$ ls *name\ 2008\ .txt    <==== make sure you only get the one file

$ mv *name\ 2008\ .txt  my_new_name.txt

Если это не отвечает вашим потребностям, дайте мне знать - есть другие подходы, использующие не-глобализация.

Насколько я понимаю, вы хотите переименовать файл или папку с неанглийскими символами, используя терминал.

Для этого вы можете использовать

mv x y

Где x - имя файла / папки, которую вы хотите переименовать, а y - новое имя, которое вы хотите для него.

Если в нем есть неанглийские символы и / или пробелы, используйте ' ' чтобы определить пределы х и у следует делать. Вот пример:

mv 'öld namé öf fileş' 'néw namé öf fileş'

Пожалуйста, поправьте меня, если я неправильно понял ваш вопрос.

Другие вопросы по тегам