Como faço para remover um arquivo no Linux cujo nome parece ser apenas um hífen, como em "-"

33

Eu tentei

rm -- -
rm "-"
rm "\-"
rm \-

Deu um tiro a Perl

~$ perl -e '$junk = glob("-"); chomp $junk; print "$junk\n"; 'rm $junk';'
-
rm: cannot remove '-': No such file or directory

... e ...

~$ perl -e '$junk = glob("-"); chomp $junk; print "$junk\n"; 'mv $junk newfile.garbage';'
-
mv: cannot stat '-': No such file or directory

Qualquer ajuda seria muito apreciada, pessoas sábias.

    
por jgrundstad 17.10.2011 / 19:07

12 respostas

60

Isso costumava ser postado nas FAQs da Usenet para o Unix - vejo que está no FAQs do GNU Core Utility . Havia pelo menos cinco métodos diferentes, mas isso funciona bem:

$ rm ./-

Se um nome de arquivo contiver caracteres não tipificáveis, use:

$ rm -i *

O sinalizador -i solicita confirmação para cada arquivo, caso deva ser removido ou não.

    
por 17.10.2011 / 19:14
39

Remover um arquivo cujos nomes começam com - é uma FAQ, mas parece que você tem um problema diferente.

Das soluções que você mencionou na pergunta:

rm -- -

Isso deve funcionar.

rm "-"

Isso não é diferente de rm - . As aspas são removidas pelo shell e o comando rm apenas vê o hífen único como um argumento. Aspas são úteis para escapar de metacaracteres de shell; o hífen é especial para rm , não para o shell.

rm "\-"

As aspas escapam da barra invertida, portanto, tenta remover um arquivo cujo nome consiste em dois caracteres, uma barra invertida e um hífen.

rm \-

Isso é igual a rm "-" , equivalente a rm - .

Por acaso, pelo menos com a versão GNU dos utilitários básicos de rm , rm - realmente remove (ou tenta remover) um arquivo cujo nome consiste em apenas um hífen. Se o seu arquivo tivesse esse nome, já teria desaparecido. Concluo que seu arquivo tem um nome que apenas parece um hífen.

ls | cat -A

deve dar uma ideia do que é realmente chamado.

Aqui está um script em Perl que eu apenas joguei juntos, que irá pedir-lhe para cada arquivo no diretório atual e perguntar se deseja removê-lo. Oferecido sem garantia, mas testei rapidamente.

#!/usr/bin/perl

use strict;
use warnings;

$| = 1;

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

foreach my $file (@files) {
    print "Remove $file? ";
    my $answer = scalar <>;
    if ($answer =~ /^[Yy]/) {
        unlink $file or warn "$file: $!\n";
    }
    elsif ($answer =~ /^[Qq]/) {
        exit 0;
    }
}

EDIT : Uma solução menos elaborada: se o nome do arquivo é apenas um caractere, então rm ? deve removê-lo (junto com qualquer outro arquivo).

    
por 17.10.2011 / 20:44
18

Se você quiser algo mais seguro ...

Tente usar uma combinação de ls e find (isso funciona para qualquer arquivo que você tenha permissão para remover)

O parâmetro '-i' lhe dará o número de inode para cada entrada de diretório ls -li

27 ----------  1 owner  group       3981 Oct 11 04:42 ?????

Depois de ter o número do inode ...

find . -inum **27** -exec rm -i {} \;
    
por 17.10.2011 / 20:58
13

Conceda rm ./- uma tentativa.

O - é um sinalizador para iniciar um argumento de sinalização. Se você iniciar o argumento com qualquer coisa que não seja - , neste caso / , ele assumirá que é o nome do arquivo. Qual é o que você deseja.

Como file e ./file são o mesmo arquivo, ele segmentará o arquivo chamado - via ./- .

    
por 17.10.2011 / 19:12
7

Não tão nerd quanto a maioria das outras respostas, mas eu acionaria uma instância de mc , midnight commander, e apenas selecionaria e excluiria o arquivo.

    
por 18.10.2011 / 10:57
7

Tente:

$ ls -b

para ver se o nome do arquivo tem caracteres não imprimíveis.

    
por 18.10.2011 / 02:22
6

Não que seja necessário usar o perl aqui, mas isso deve funcionar:

perl -e 'unlink "-"'

ou para ver o que qualquer erro com o acima pode ser:

perl -e 'unlink "-" or die "Err: $!"'
    
por 17.10.2011 / 20:27
3

Eu tive sorte usando o Nautilus do GNOME para remover arquivos mal nomeados. Você está executando um servidor X? Tenho certeza de que outros navegadores de arquivos também funcionariam.

    
por 17.10.2011 / 19:32
3

Se

rm -- -

não funcionou, o nome do arquivo não é "apenas um hífen". Se nenhum outro arquivo tiver um hífen, você pode tentar

perl -E'for (@_) { if (/-/) { unlink($_) or die $! } }' -- *
    
por 17.10.2011 / 20:53
1

Até agora, recebi um "Nenhum arquivo ou diretório desse tipo" para todos os métodos publicados até o momento:

rm ./-
rm -- -
mv "-" test.txt
rm -rf '-' <-- this gives no error, but doesn't work
perl -e 'unlink "-";'  <--also no error, doesn't work.

Parece que eu tenho rm versão 7.4. Vou tentar atualizar e tentar novamente essas sugestões. Obrigado a todos por ajudarem.

    
por 17.10.2011 / 20:48
1

Eu gosto muito de usar o modo dired no emacs para esse tipo de coisa - apenas "abra" o diretório no emacs. Você pode facilmente selecionar arquivos e marcá-los para exclusão.

Outro pôster sugerido usando o comando da meia-noite; esta é praticamente a mesma ideia, mas se você já é um usuário do emacs talvez seja mais conveniente.

    
por 18.10.2011 / 15:53
0

Deve ser capaz de fazer rm -f '-' trabalhado para mim no cygwin

Para esse assunto, rm - também parece funcionar no Red Hat.

    
por 17.10.2011 / 19:11

Tags