.png)
Недавно я наткнулся на файл, имя которого начинается с символа '♫'. Я хотел скопировать этот файл, передать его в 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