web-dev-qa-db-ja.com

ファイル名に印刷できない文字が含まれているファイルを削除するにはどうすればよいですか

どういうわけか、ファイル名がないように見えるファイルを作成することができました。次の thread。 で、ファイルの詳細を取得する方法に関するいくつかの情報を見つけました

しかし、私はリストされているいくつかの提案を試してみましたが、ファイルを削除できないようです。それを作成するために何をしたかはわかりませんが、xmlファイルをコピーしようとしたときに発生しました。

ファイルに関するいくつかの情報は次のとおりです。

> ls -lb
total 296
-rw-r--r--   1 voyager  endeavor  137627 Jan 12 12:49 \177

> file *
:               XML document

> ls -i
 417777   

私はinumスイッチの使用を見つけてそれをrmにパイプしようとしましたが、それはそれを取り除く最も簡単な方法のように思えました。しかし、下にリンクされているスレッドの下部にある例は私にとって失敗しました。例は:

> find -inum 41777 -exec ls -al {} \;
find: illegal option -- i
find: [-H | -L] path-list predicate-list

だから私は最初に次のようにパスリストを使ってみましたが、それもうまくいきませんでした:

> find . -inum 41777 -exec ls -al {} \;

印刷できない文字\ 177が何であるか、またはどのようにrmコマンドに渡すことができるかはわかりませんが、自分の他のファイルやディレクトリを台無しにしないようにしたいのですがこのファイルを削除してみてください。

48
Mr Moose

ファイルには名前がありますが、印刷できない文字で構成されています。 ksh93、bash、zsh、mksh、またはFreeBSD shを使用している場合は、印刷できない名前を指定して削除を試みることができます。まず、名前が正しいことを確認します:ls -ld $'\177'正しいファイルが表示されている場合は、rmを使用します:rm $'\177'

別の(少し危険な)アプローチはrm -i -- *。 -iオプションを使用すると、rmはファイルを削除する前に確認を要求するので、残しておきたい1つのファイル以外のすべてのファイルをスキップできます。

幸運を!

48
antje-m

vimを使用する場合は、現在の作業ディレクトリで実行してください。

$ vim ./ 

矢印キーまたはj/kでファイルに移動します。次にShift+Dを押し、yで削除を確認します。

24
user13742

ファイル名をrmに渡す方法はおそらくあるでしょうが、何かを台無しにすることが心配な場合は、GUIファイルマネージャを使用できます。 Emacsには、インストールされている場合に使用できるディレクトリ編集モードが付属しています。

  1. emacsのフォルダーを開きます。 emacs /path/to/folder、またはemacsを開き、ヒット Esc+x、およびdiredを実行すると、パスの入力を求められます

    http://so.mrozekma.com/unix-dired-delete1.png

  2. 削除したいファイルがある行に移動して、 d。ファイルの横の左マージンにDが表示されます。

    http://so.mrozekma.com/unix-dired-delete2.png

  3. 押す x 変更を保存します。ファイルを削除するかどうかを確認するメッセージが表示されます。押す y

    http://so.mrozekma.com/unix-dired-delete3.png

9
Michael Mrozek

シェルグロブ(file *)がこのファイルを取得できることを*ですでに示したので、このグロブに対してrmを実行するだけです。

  • ファイルがあるディレクトリに移動します。
  • rm -i *を実行します
  • 一見して見えないファイル名のファイルを除くすべてのファイルにnを入力します
8
Patrick

ファイルには実際には名前がありますが、印刷できない文字で構成されています。

簡単な方法は、シェルの完了に依存することです。 Tab 「奇妙な」ファイル名が挿入されるまで繰り返し。可能な完了の間を循環するようにシェルを構成する必要があります。

  • Bashでは、バインドされているcompleteではなく、デフォルトでバインドされていないmenu-completeを呼び出す必要があります。 Tab デフォルトでは。または、 Esc* すべてのファイルの補完を挿入し、削除したくないものをコマンドラインから削除します。
  • Zshでは、デフォルト設定で問題ありません。 setopt auto_menuまたはsetopt menu_completeを設定する必要があります。

シェルで補完が役に立たない場合は、rm -i -- *を呼び出して、この特定のファイルを除いて「いいえ」と答えることができます。ファイル名が印刷可能な文字で始まっていない場合は、最初の文字が印刷可能な文字のセットにないファイルに一致を制限できます。

rm -i [!!-~]*
rm -i [![:print:]]*
rm -i -- [!a-z]

(パターンが-fというファイルと一致する場合があることに注意してください。rmはオプションとして扱います。)

別の方法は、ls -iを呼び出してファイルのiノード(inodeは特定のファイルシステム上のファイルを一意に識別する)を検索し、次にfind -inumを呼び出してその特定のファイルを操作する方法です。この方法は、ディレクトリに多くのファイルが含まれている場合に最も役立ちます。

ls -i
# note the inode number 12345
find . -xdev -inum 12345 -delete

find-deleteオプションがない場合は、rmを呼び出します。

find . -xdev -inum 12345 -exec rm -- {} \;

(はい、これのほとんどが既に投稿されていることは知っています。しかし、関連する情報を使用した回答により、これは必要以上に複雑になっています。)

echo -eを使用して文字\177を取得し、次にxargsを使用してrmに渡します。 echoは10進エスケープをとらないため、16進数に変換します。177は8進数であることがわかります。 echoの前には\0(リテラル、nullバイトではない)が必要です:

echo -ne '\0177\0' | xargs -0 rm
4
Kevin

ファイルが名前を持っていることを保証します。たまたま、印刷できない文字を含む名前です。

rmが機能しない場合は、-inumオプションを指定したfindの出力をrmへの引数として使用しても効果がありません。同じ問題で、rmに同じ引数を渡すだけです。

ファイルはそのディレクトリで唯一のものですよね?

まず、cdをディレクトリに入れ、次にrm ./と入力して、Tabキーを押します。これにより、引数がファイルの実際の名前に展開され、前の./rmが引数をファイル名以外のものとして解釈するのを防ぐ必要があります。

別の解決策は、親ディレクトリにcdを使用し、そのディレクトリでrm -r(または、必要に応じてrm -rf)を使用することです。名前に関係なく、ディレクトリとそのすべての内容が削除されます。次に、mkdirを使用してディレクトリを再作成できます(おそらくchmodを使用して、そのアクセス許可を復元できます)。

編集:

ls -lbの出力をもう一度見ると、ファイル名はASCII DEL文字(これは致命的ではありませんが悪い)および改行文字が1つ以上含まれています(これは本当に悪いことです)私の知る限り、rmコマンドは改行をファイル名の一部として解釈できません。

しかし、unlink()システムコールはできます。これは私が一緒に投げたPerlスクリプトで、現在のディレクトリ内のファイルを繰り返し処理し、削除するかどうかを尋ねます。 rmのような外部コマンドを使用してファイルを削除しないため、ファイルシステムがサポートするおかしな文字(ASCII NULおよび/以外)を処理できる必要があります。

含まれているディレクトリでrm -rまたはrm -rfを実行しても機能しますが、単一のファイルを削除するだけの場合は、これを試すことができます。

#!/usr/bin/Perl

use strict;
use warnings;

opendir my $DIR, '.' or die ".: $!\n";
my @files = sort grep { -f } readdir $DIR;
closedir $DIR;

foreach my $file (@files) {
    my $pfile = printable($file);
    print "Remove $pfile? ";
    my $answer = scalar <STDIN>;
    if ($answer =~ /^[Yy]/) {
        print "Removing $pfile\n";
        unlink $file or warn "Unable to remove $pfile: $!\n";
    }
}

sub printable {
    my($s) = @_;
    $s =~ s/[^ -~]/?/g;
    return $s;
}

(保持したいディレクトリに他のファイルがある場合の別の解決策は、他のすべてのファイルを一時ディレクトリに移動してから、ディレクトリをnukeして再作成し、他のファイルを元に戻すことです。)

(ああ、そのファイルを作成するために何をしたとしても、二度と作成しないようにしてください!)

3
Keith Thompson

あなたは近いです。手順を追って、iノード番号でファイルを削除する方法を説明します。

最初に、ls -liを使用して、必要なファイルのiノード番号を見つけます。 iノード番号は出力の最初の列に表示されます。

例えば:

$ls -li
311010 -rw-rw-r-- 1 me me 3995 Apr  6 16:27 -???\# ;-)

この場合、iノード番号は311010です。

findを使用して、iノード番号でファイルを検索します。

find . -inum 311010 

findが削除するファイルの名前のみを返すことを確認してください。例えば:

$find . -inum 311010
./-???\# ;-)

findが正しいファイルを見つけていることを確認したら、-deleteパラメータをfindに渡します。ファイルが削除されます。

find . -inum 311010 -delete
2
Christian Long

findコマンドを使用して正確にそのファイルを見つけることができる場合、-delete述語を使用できます。ただ注意して、-deleteをfindコマンドの最後のパラメーターにしてください。

1
Michał Šrajer

すべてのファイルには名前が付いています。正確にどれを見つける必要があります。

このファイルを例として使用します。

$ touch $'\177' $'\001\002' $'\033\027' a b abc $'a\177b'

これらのファイルは、通常のlsでは?と表示されます。

$ ls
??  ?  ?002  a  abc  b

ただし、ls-Qオプションを許可している場合は、実際のファイル名を明確にする必要があります。

$ ls -1iQ *
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739118 "a"
26739121 "a\177b"
26739120 "abc"
26739119 "b"

これらは、pwd内のファイルの1列にあるiノード番号と「引用」された名前です。

(POSIX)シェルの機能を使用して、拡張(グロビング)を使用しています。

名前に非印刷文字を含めるには:

$ ls -1iQ *[![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"
26739121 "a\177b"

only非印刷文字が含まれている可能性のあるファイルを一覧表示するには、次のように入力します。

$ ls -1iQ [![:print:]]*
26739122 "\001\002"
26739117 "\033\027"
26739115 "\177"

次に、選択的に(-i(インタラクティブ)オプション)それらを削除するには:

$ rm -i [![:print:]]*
rm: remove regular file ''$'\001\002'? n
rm: remove regular file ''$'\033\027'? n
rm: remove regular file ''$'\177'? n

上記の質問にyと答えて、消去するものを選択するだけです。

0
Isaac

代わりに、現在のディレクトリの名前をDirX_OLDに変更し、DirXという名前で新しいディレクトリを作成して、必要なすべてのファイルをDirX_OLDからDirXに移動できます。ファイルをコピーしたら、削除できますDirX_OLD

0
user106382

万が一に備えて、2セント相当の金額を追加します。次のように、ワイルドカードで stat を使用してファイル名を取得できました。

stat -c %N *

出力:

`\220g\201\acontexts'
`\220g\201\alogins'
`\220g\201\amodules'
`\220g\201\apolicy'
`\220g\201\asetrans.conf'

次に、 ANSI Cで引用された文字列 (受け入れられた回答で使用されている)を使用してファイルにアクセスできます。

rm $'\220g\201\asetrans.conf'
0
miken32

オートコンプリートを備えたbashがある場合は、これでうまくいく場合があります。ディレクトリリストに表示された文字を入力しました。次に、オートコンプリートをトリガーし、印刷可能なものに名前を変更しました。

これが私のために働いたものです:

$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 ?
$ mv ?  
(hit the [tab] and it gets extended to ...)
$ mv ^[
(now complete the command and rename to something printable)
$ mv ^[ weirdchar
$ ll
-rw-r--r--.  1 xxxxxxxx  xxxxx 25608 Oct 11 11:11 weirdchar
(now delete)
$ rm weirdchar
0
Sascha

他の答えは素晴らしく、ほとんどすべての環境で機能します。

ただし、GUIが実行されている場合は、nautilus、dolphin、konqueror、またはお気に入りのファイルマネージャーでディレクトリを開くだけで、マウスを数回クリックするだけで、協力しない名前のファイルを簡単に表示して削除できます。 。

通常のemacsまたはvimユーザーでない場合(他のいくつかの回答で取り上げられています)、これが最も簡単な方法です。

0
Joe

「\ 033」(実際の「エスケープ」文字)という名前のファイルに同様の問題がありました。

for x in $( ls | awk '!/^[A-Z]/ && !/^[a-z]/ && !/^[0-9]/');do rm -i -- $x ; done

上記は、現在のディレクトリで文字または数字で始まらないファイルを削除するように促します。

0
Signal15