.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 行目を印刷し、16 進数でエンコードします。
$ /bin/ls -1A|sed -n 5p|xxd -g 1
0000000: e2 99 ab 0a ....
0a (改行) 文字を無視してエスケープ文字列を作成し、echo の -e オプションを使用してエスケープを変換します。
$ 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
シンボリックリンクの名前を変更する
ファイル名の先頭文字または他の部分に特殊文字が含まれるファイル名を処理する方法の1つは、よりシンプルな名前に変更する。
必要に応じて使用できます元のファイル名を維持する: ファイル名のコピーの名前を変更します。
これはファイルをコピーすることでも実行できますが、シンボリックリンクまたはハードリンクファイルにcp
コピーして名前を変更します。オプション-s
(-l
ハードリンクの場合は )を使用すると、コピーではなくシンボリックリンクが作成されます。
名前をきれいにするには「デトックス」を使う
きれいなファイル名に変更するには、detox
使用できる。これは、ファイルの名前を変更して、さまざまなルールに従ってファイル名を整理します。detoxrc
ファイル。デフォルトでは、UTF8 文字は削除されるだけです。オプションを指定すると、次の文字-s utf_8-only
に置き換えられます_
。
$ touch '♫ 漢字カ' ♫foo
$ ls -1
♫foo
♫ 漢字カ
$ detox -s utf_8-only *
$ ls -1
_ ___
_foo
シンボリックリンクの「detox」
上記のようなシンボリックリンクの作業と組み合わせると、次のようになります。
$ 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