Como posso apagar um arquivo cujo nome de arquivo não contenha caracteres?

44

De alguma forma, consegui criar um arquivo que não parece ter um nome de arquivo. Eu encontrei algumas informações sobre como obter mais detalhes do arquivo no seguinte thread.

No entanto, tentei algumas das sugestões listadas e não consigo excluir o arquivo. Não tenho certeza do que fiz para criá-lo, mas aconteceu ao tentar copiar um arquivo xml.

Algumas informações sobre o arquivo são as seguintes:

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

> file *
:               XML document

> ls -i
 417777   

Eu tentei encontrar usando o switch inum e depois canalizar isso para rm, já que isso parecia a maneira mais infalível de se livrar dele. No entanto, o exemplo dado na parte inferior do encadeamento vinculado abaixo falhou para mim. Exemplo foi:

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

então tentei usar a lista de caminhos primeiro como a seguinte, mas isso também não funcionou:

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

Não tenho certeza do que o caractere não imprimível \ 177 é ou como posso transmiti-lo para um comando rm , mas realmente quero ter certeza de que não vou atrapalhar nenhum outro arquivo / diretório na minha conta. tente excluir este arquivo.

    
por Mr Moose 13.01.2012 / 02:30

15 respostas

43

O arquivo tem um nome, mas é feito de caracteres não imprimíveis. Se você usa ksh93, bash, zsh, mksh ou FreeBSD sh, você pode tentar removê-lo especificando seu nome não-imprimível. Primeiro, verifique se o nome está correto com: ls -ld $'7' Se mostrar o arquivo correto, use rm: rm $'7'

Outra abordagem (um pouco mais arriscada) é usar rm -i -- * . Com a opção -i, o rm requer confirmação antes de remover um arquivo, portanto, você pode pular todos os arquivos que deseja manter, exceto o arquivo.

Boa sorte!

    
por 13.01.2012 / 02:57
23

Para quem usa vim , execute-o no diretório de trabalho atual:

$ vim ./ 

e navegue até o arquivo com as teclas de seta ou j/k . Em seguida, pressione Shift+D e confirme a exclusão com y .

    
por 13.01.2012 / 03:05
9

Provavelmente, existe uma maneira de passar o nome do arquivo para rm , mas se você está preocupado em mexer em algo, pode usar um gerenciador de arquivos GUI. O Emacs vem com um modo de edição de diretório que você pode usar se tiver instalado:

  1. Abra a pasta em emacs . Você pode executar emacs /path/to/folder ou abrir o emacs, teclar Esc + x e executar dired , que solicitará o caminho

    link

  2. Mova para a linha com o arquivo que você deseja apagar e pressione d . Você deve ver um D na margem esquerda ao lado do arquivo:

    link

  3. Pressione x para salvar suas alterações. Ele solicitará que você deseje excluir o arquivo; pressione y :

    link

por 13.01.2012 / 02:47
8

Você já demonstrou com file * que o shell glob ( * ) é capaz de pegar esse arquivo, então faça um rm nesse glob.

  • Altere para o diretório no qual o arquivo está.
  • Executar rm -i *
  • Insira n para todos os arquivos, exceto para aquele com o nome de arquivo aparentemente invisível
por 13.01.2012 / 04:12
7

O arquivo realmente tem um nome, mas é feito de caracteres não imprimíveis.

Um método fácil é confiar na conclusão do shell: pressione Tab repetidamente até que o nome do arquivo “estranho” seja inserido. Você deve ter seu shell configurado para alternar entre possíveis conclusões:

  • No bash, você precisa invocar menu-complete , que não está vinculado por padrão, em vez de complete , que está vinculado à Tab por padrão. Alternativamente, use Esc * para inserir conclusões para todos os arquivos, e remova os que você não deseja excluir da linha de comando.
  • Em zsh, as configurações padrão são boas; você precisa ter setopt auto_menu ou setopt menu_complete set.

Se a conclusão não for útil em seu shell, você pode chamar rm -i -- * e responder "não", exceto para este arquivo específico. Se o nome do arquivo não começar com um caractere imprimível, você poderá restringir as correspondências a arquivos cujo primeiro caractere não esteja em um conjunto de caracteres imprimíveis:

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

(Cuidado se seu padrão pode corresponder a um arquivo chamado -f , que rm trataria como uma opção).

Outro método é chamar ls -i para encontrar o inode do arquivo (um inode identifica exclusivamente um arquivo em um determinado sistema de arquivos) e, em seguida, find -inum para operar nesse arquivo em particular. Este método é mais útil quando o diretório contém muitos arquivos.

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

Se sua opção find não tiver -delete , chame rm :

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

(Sim, eu sei que a maior parte já foi postada. Mas as respostas com as informações relevantes estão tornando isso mais complicado do que deveria.)

    
por 14.01.2012 / 02:01
3

Tente usar echo -e para obter o caractere 7 e, em seguida, xargs para passá-lo para rm . echo não usa escravo decimal, então converta em hex: Desativa o 177 is octal; echo requer um %code% (literal, não um byte nulo) antes:

echo -ne '77
echo -ne '77%pre%' | xargs -0 rm
' | xargs -0 rm
    
por 13.01.2012 / 02:52
3

Eu posso garantir que o arquivo tem um nome. Apenas é um nome que contém caracteres não imprimíveis.

Se rm não funcionou, usar a saída de find com a opção -inum como argumento para rm provavelmente não ajudará; vai passar o mesmo argumento para rm , com o mesmo problema.

O arquivo é o único desse diretório, certo?

A primeira coisa que eu tento é cd no diretório, então digite rm ./ , então aperte a tecla Tab. Isso deve expandir o argumento para o nome real do arquivo, e o ./ anterior deve impedir que rm interprete o argumento como algo diferente de um nome de arquivo.

Outra solução é cd para o diretório pai e, em seguida, use rm -r (ou, se necessário, rm -rf ) no diretório. Isso deve remover o diretório e todo o seu conteúdo, independentemente do nome. Você pode usar mkdir para recriar o diretório (e talvez chmod para restaurar suas permissões).

EDITAR:

Olhando sua saída ls -lb novamente, acho que o nome do arquivo começa com um caractere ASCII DEL (que é ruim, não não fatal) e contém um ou mais caracteres de nova linha (que é muito ruim). Tanto quanto eu posso dizer, o comando rm não pode interpretar uma nova linha como parte de um nome de arquivo.

Mas a chamada do sistema unlink() pode. Aqui está um script em Perl que eu joguei juntos que irá percorrer os arquivos no diretório atual, e pedir-lhe para cada um se você deseja removê-lo. Ele não usa um comando externo como rm para remover os arquivos, portanto deve ser capaz de manipular quaisquer caracteres engraçados que o sistema de arquivos suportar (qualquer coisa diferente de ASCII NUL e / ).

Fazer rm -r ou rm -rf no diretório que contém ainda deve funcionar, mas se você quiser apenas remover um único arquivo, tente isso.

#!/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;
}

(Outra solução, se houver outros arquivos no diretório que você deseja manter, é mover todos os outros arquivos para um diretório temporário, em seguida, fortaleça e recrie o diretório e mova os outros arquivos de volta.)

(Ah, e o que você fez para criar esse arquivo, tente não fazer isso de novo!)

    
por 13.01.2012 / 02:56
1

Se você puder encontrar exatamente esse arquivo usando o comando find , poderá usar o predicado -delete . Apenas tome cuidado, e faça do -delete um último parâmetro do comando find ou ele vai doer muito ...

    
por 13.01.2012 / 03:05
1

Você está perto. Passo a passo, veja como excluir o arquivo pelo número do inode.

Primeiro, encontre o número de inode do arquivo desejado, usando ls -li . O número do inode estará na primeira coluna de saída.

Por exemplo:

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

Neste caso, o número do inode é 311010

Use find para procurar o arquivo pelo número do inode.

find . -inum 311010 

Certifique-se de que find retorne apenas o nome do arquivo que você deseja excluir. Por exemplo:

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

Quando tiver certeza de que find está localizando o arquivo correto, passe o parâmetro -delete para find . Ele excluirá o arquivo para você.

find . -inum 311010 -delete
    
por 14.04.2015 / 21:26
0

As outras respostas são ótimas e funcionam em quase todos os ambientes.

Mas, se acontecer de você ter um GUI em execução, basta abrir o diretório no nautilus, dolphin, konqueror ou seu gerenciador de arquivos favorito e você poderá ver e excluir facilmente qualquer arquivo que tenha um nome não cooperativo com um par. de cliques do mouse.

Se você não é um usuário regular do emacs ou vim (como aparece em várias outras respostas), esse pode ser o caminho mais fácil.

    
por 14.01.2012 / 10:24
0

Tive um problema semelhante com um arquivo chamado "\ 033" (o verdadeiro caractere "Escape").

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

O texto acima solicitará que você remova os arquivos no diretório atual que não iniciam com uma letra ou número.

    
por 05.01.2015 / 20:44
0

Em vez disso, você pode renomear o diretório atual para DirX_OLD , criar um novo diretório com o nome DirX e mover todos os arquivos necessários de DirX_OLD para DirX . Depois de copiar os arquivos, você pode excluir DirX_OLD

    
por 12.03.2015 / 19:21
0

Apenas no caso de ajudar alguém, adicionarei meus dois centavos. Consegui obter o (s) nome (s) de arquivo usando stat em o curinga como este:

stat -c %N *

Saída:

'0g1\acontexts'
'0g1\alogins'
'0g1\amodules'
'0g1\apolicy'
'0g1\asetrans.conf'

Em seguida, eu poderia usar strings ANSI C entre aspas (conforme usado em a resposta aceita) para acessar os arquivos:

rm $'0g1\asetrans.conf'
    
por 18.01.2018 / 01:38
0

Cada arquivo tem um nome, você só precisa encontrar exatamente qual.

Vou usar esses arquivos como exemplos:

$ touch $'7' $'
$ ls
??  ?  ?002  a  abc  b
1
$ ls -1iQ *
26739122 "
$ ls -1iQ *[![:print:]]*
26739122 "
$ ls -1iQ [![:print:]]*
26739122 "
$ rm -i [![:print:]]*
rm: remove regular file ''$'
$ touch $'7' $'
$ ls
??  ?  ?002  a  abc  b
1
$ ls -1iQ *
26739122 "
$ ls -1iQ *[![:print:]]*
26739122 "
$ ls -1iQ [![:print:]]*
26739122 "
$ rm -i [![:print:]]*
rm: remove regular file ''$'%pre%1%pre%2'? n
rm: remove regular file ''$'37'? n
rm: remove regular file ''$'7'? n
1%pre%2" 26739117 "37" 26739115 "7"
1%pre%2" 26739117 "37" 26739115 "7" 26739121 "a7b"
1%pre%2" 26739117 "37" 26739115 "7" 26739118 "a" 26739121 "a7b" 26739120 "abc" 26739119 "b"
2' $'37' a b abc $'a7b'
1%pre%2'? n rm: remove regular file ''$'37'? n rm: remove regular file ''$'7'? n
1%pre%2" 26739117 "37" 26739115 "7"
1%pre%2" 26739117 "37" 26739115 "7" 26739121 "a7b"
1%pre%2" 26739117 "37" 26739115 "7" 26739118 "a" 26739121 "a7b" 26739120 "abc" 26739119 "b"
2' $'37' a b abc $'a7b'

Esses arquivos serão exibidos como ? no% normalls:

%pre%

Mas se a sua ls permitir a opção -Q , deve ficar claro qual é o nome real do arquivo:

%pre%

esses são os números de inode e os nomes "Quoted" na coluna 1 dos arquivos em pwd.

Isso é usando a habilidade de um shell (POSIX) para usar expansões (globbing):

Para ter os nomes com qualquer caractere não imprimível:

%pre%

E para listar arquivos que podem ter apenas caracteres não imprimíveis:

%pre%

Em seguida, para seletivamente (a opção -i (interativo)), remova-os:

%pre%

Você só precisa escolher quais apagar, respondendo y à pergunta acima.

    
por 03.10.2018 / 04:20
-4
rm -dfvr /"(null)" 

funcionou para mim.

    
por 01.09.2015 / 15:57