web-dev-qa-db-ja.com

ファイル名に特殊文字を含むファイルを削除/移動できません

以下に示すように、ファイルには一般的でない文字が含まれています。

file manager screenshot

端末またはDolphinでそれらを削除すると、エラーが返されます。

そのようなファイル、又はディレクトリはありません

ディレクトリでls -laを実行すると、次の出力が得られました。

-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ?2?.???љ?!?Gb??σ?[?F?
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 3l??#g?w????O?JKB7?co??քH??bT?NA???S???X?I?A?qC??M?I???
-rw-rw-r--  1 aalap aalap      0 Nov 14 01:05 ??8??-?@,?Zp?[?bI????7^?ñ[?ڏ??z?O???ч??eEȰ?+??,OF??h

別のOSのパーティションでfsckコマンドを実行しましたが、何も変わりませんでした。

これらのファイルを削除するにはどうすればよいですか?

17
karjedavpalaa

簡単な方法は、これらのファイルをiノードで削除することです。 :)

ディレクトリでls -liを使用して、一般的でない文字を使用して、各ファイルのiノード番号を表示します。

$ ls -li
total 0
133370 -rw-r--r-- 1 malte malte 0 Dec 30 19:00 ?2?.???љ?!?Gb??σ?[?F?
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

次に、findユーティリティを使用して、次の例のように、構文find <somepath> -inum <inode_number> -exec rm -i {} \;を使用して、名前で対応するファイルを削除します。

$ find . -inum 133370 -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
$ ls -li
total 0
132584 -rw-r--r-- 1 malte malte 0 Dec 30 18:59 ??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??

rm-iオプションは必ずしも必要ではありません。削除するつもりのないファイルを誤って削除しないようにするために追加しただけです。 :) rmは、削除する各ファイルの確認を要求します。

Iノードによって複数のファイルを削除する場合は、findに対して-o(つまりまたは)構文を使用できます。

$ find .  \( -inum 133370 -o -inum 132584 \) -exec rm -i {} \;
rm: remove regular empty file ‘./?2?.???љ?!?Gb??σ?[?F?’? y
rm: remove regular empty file ‘./??3]d???:????????1????G?p?ȋ??????嫳?d????ą-??’? y

括弧内の式をさらに-o -inum <inode_number>式で拡張することにより、inode番号を追加できます。

35
Malte Skoruppa

これはnotfsckが役立つ「ファイルシステムの破損」ではないことを理解することが重要です。ファイルシステムに関する限り、単一バイトの値が0x00(ASCII NUL、C)でない限り、ファイル名は任意のバイトシーケンスにできます。文字列の終わりマーカー)または0x2F(/、ディレクトリ区切り記号)。 (ファイル名に何らかの理由で00または2Fバイトが埋め込まれている場合、fsckはそれを修正する必要があります。)

むしろ、アプリケーションソフトウェア(Dolphin、ls)が、「ロケールにun-displayableである文字を含むと考えるファイル名です。 」なので、プレースホルダー文字に置き換えています。これらの文字はtypeすることもできないため、ファイルの操作は難しくなりますが、入力やコピーをせずに実行する限り実行できます名前を貼り付けます。たとえば、問題のファイルをDolphin内から直接削除または名前を変更した場合、うまくいくはずです(うまくいかない場合、それはDolphinのバグです)。

シェルからそれらについて何かを行う必要がある場合(たとえば、それらがrootによって所有されているため、GUIプログラムで変更できない場合)、「glob」パターンを使用して間接的に名前を付けることができます。正しいバイトシーケンスに展開されて渡されます。

もちろん、グロブパターンが一致しすぎたため、偶発的なものを削除したくないので、Perl renameユーティリティを使用して各ファイル名を16進エンコーディングに変換することをお勧めします。

$ rename '$_ = unpack("H*", $_)' *

これは情報を破壊しません-ファイル自体も、破壊される前に元々ファイル名にエンコードされていた意味もありません。たとえば、特定のファイルに対して元に戻すことができます。

$ rename '$_ = pack("H*", $_)' 696d706f7274616e742e646f63

注意:起源が異なるrenameという名前の2つのプログラムがあります。上記のコマンドは、Perlで作成されたコマンドでのみ機能します。 Ubuntuでは、必要なのは「util-linux」パッケージからではなく、「rename」パッケージからのものです。 rename -hは区別します。これはあなたが望むものです...

$ rename -h
Usage:
    rename [ -h|-m|-V ] [ -v ] [ -n ] [ -f ] [ -e|-E perlexpr]*|perlexpr
    [ files ]
# ...

...これはあなたが望むものではありません...

$ rename -h

Usage:
 rename [options] <expression> <replacement> <file>...
# ...

探すべき重要なことは「perlexpr」です。上記のすべてのオプションを理解していない古いバージョンのPerlの名前変更があるかもしれませんが、私が示したコマンドはまだ機能するはずです。

編集:14.04 .5では、renameに含まれているPerlスクリプトは-hスイッチをサポートしていません。 man renameでそのマニュアルページをチェックすることにより、正しいものを持っていることを確認できます。その場合、一番上の行には以下が含まれます:

RENAME(1)PerlプログラマーズリファレンスガイドRENAME(1)

13
zwol