Работа с именами файлов, содержащими специальные первые символы (например, ♫)

Работа с именами файлов, содержащими специальные первые символы (например, ♫)

Недавно я наткнулся на файл, имя которого начинается с символа '♫'. Я хотел скопировать этот файл, передать его в ffmpegи ссылаться на него другими способами в терминале. Обычно я автоматически дополняю странные имена файлов, но это не получается, так как я даже не могу ввести первую букву.

Я не хочу переключаться на мышь, чтобы выполнить маневр копирования-вставки. Я не хочу запоминать кучу кодов для возможных сценариев. Моим импровизированным решением было переключиться на vim, вставить !lsи скопировать нужный символ, затем выйти и вставить его в терминал. Это сработало, но довольно ужасно.

Есть ли более простой способ справиться с такими сценариями?

ПРИМЕЧАНИЕ:Я использую рыбью раковину, если это что-то меняет.

решение1

Если первый символ имени файла является печатным, но не является ни буквой, ни цифрой, ни пробелом, вы можете использовать [[:punct:]]оператор glob:

$ ls *.txt
f1.txt  f2.txt  ♫abc.txt
$ ls [[:punct:]]*.txt
♫abc.txt

решение2

Самое простое, что приходит мне в голову, ls [^a-zA-Z0-9]*и оно мне подходит, но ответ terdon лучше привлекает внимание к варианту оболочки extglob или даже к подходу, независимому от оболочки.

решение3

У ls есть несколько ключей (например, --quote-name, --escape, --literal) для работы с непечатаемыми символами, но в этом случае, похоже, символ «печатается», но не «набирается» (по крайней мере, на моей клавиатуре!), так что ни один из этих ключей, похоже, не помогает.

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

$ /bin/ls -1A|cat -n  # list all files (except . and ..), 1 per line, add line numbers
     1  ♫
     2  f1.txt
     3  f2.txt

Найдите строку, содержащую проблемный файл. Скорее всего, это будет 1-я строка, но предположим, что это 5-я. Выведите строку 5 и закодируйте ее в шестнадцатеричном формате:

$ /bin/ls -1A|sed -n 5p|xxd -g 1
0000000: e2 99 ab 0a                                      ....

Игнорируя символ 0a (новая строка), создайте escape-строку и используйте опцию -e команды echo для перевода escape-последовательностей:

$ echo -e '\xe2\x99\xab'

Теперь вы можете скопировать/переместить/удалить его следующим образом:

$ cp -vi $(echo -e '\xe2\x99\xab') better_name
‘♫’ -> ‘better_name’

Кроме того, если вы не ограничены использованием скрипта оболочки, вы можете сделать это на Python следующим образом:

$ python
>>> import os
>>> os.listdir('.')
[ ..., '\xe2\x99\xab', ... ]
>>> print '\xe2\x99\xab'
>>> import shutil
>>> shutil.copy('\xe2\x99\xab', 'better_name')

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

for f in os.listdir('.'):
  if not f.isalnum():
    newname = generate_newname(f)
    if not os.path.exists(newname):
      shutil.copy(f, newname)
    else:
      print newname, 'already exists!'

решение4

Переименовать символические ссылки

Один из подходов к обработке имен файлов со специальными символами — в качестве первых символов или в других местах имени файла — этопереименовать в более простые имена.

Это можно использовать, даже если вам нужносохранить исходные имена файлов: Переименовать копию имен файлов.
Это можно сделать, скопировав файлы, но также и создавсимволические или жесткие ссылкик файлам и переименуйте их. cpсоздает символические ссылки вместо копий с опцией -s( -lдля жестких ссылок).

Используйте «детокс» для очистки имен

Для переименования файлов в чистые имена,detoxможет быть использован; Он переименовывает файлы, чтобы очистить имена файлов в соответствии с различными правилами, определенными вdetoxrcфайл. По умолчанию символы UTF8 просто удаляются; с опцией -s utf_8-onlyони заменяются на _:

$ touch '♫ 漢字カ' ♫foo
$ ls -1
♫foo
♫ 漢字カ
$ detox -s utf_8-only * 
$ ls -1                
_ ___
_foo


«детокс» на символических ссылках

В сочетании с работой над символическими ссылками, как описано выше:

$ mkdir orig
$ cd orig 
$ touch '♫ 漢字カ' ♫foo
$ cd ..
$ mkdir clean
$ cd clean 
$ cp -s ../orig/* .
$ ll               
lrwxrwxrwx 1 14 Oct  8 05:52 ♫foo -> ../orig/♫foo
lrwxrwxrwx 1 21 Oct  8 05:52 ♫\ 漢字カ -> ../orig/♫\ 漢字カ
$ ls -1
♫foo
♫ 漢字カ
$ detox --special -s utf_8-only *
$ ll                                
lrwxrwxrwx 1 21 Oct  8 05:52 _\ ___ -> ../orig/♫\ 漢字カ
lrwxrwxrwx 1 14 Oct  8 05:52 _foo -> ../orig/♫foo

Связанный контент