Impossibile eliminare / spostare i file con caratteri speciali nel nome del file


17

Come puoi vedere sotto, i file hanno caratteri non comuni.

screenshot del file manager

La loro eliminazione nel terminale o Dolphin restituisce l'errore:

Nessun file o directory con questo nome

In esecuzione ls -lasulla directory mi ha dato questo output:

-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

Ho eseguito un fsckcomando sulla partizione da un altro sistema operativo ma non ha cambiato nulla.

Come rimuovo questi file?


1
Hai configurato il tuo sistema per avere una home directory crittografata?
Dobey,

@dobey non l'ho fatto.
Karjedavpalaa,

5
@Panther Ti sbagli. Questo non è , di per sé, un'indicazione di un file system corrotto, e anche se è stato causato da una corruzione dei dati di qualche tipo, fsck non farà nulla al riguardo.
zwol,


1
Ho avuto file con caratteri non riconosciuti nel nome. Rinominare i file ha funzionato. quindi potrebbero essere eliminati.
Ravery,

Risposte:


35

Un modo semplice sarebbe quello di rimuovere questi file dal loro inode. :)

Utilizzare ls -linella directory con i caratteri non comuni per mostrare il numero di inode di ciascun file, ad es.

$ 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????ą-??

Quindi, utilizzare l' findutilità per eliminare il file corrispondente in base al nome, utilizzando la sintassi find <somepath> -inum <inode_number> -exec rm -i {} \;, come nell'esempio seguente:

$ 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????ą-??

L' -iopzione a rmnon è davvero necessaria, l'ho appena aggiunta per impedirti di rimuovere accidentalmente i file che non intendevi rimuovere. :) Fa rmchiedere conferma per ogni file che si desidera eliminare.

Se si desidera rimuovere più file tramite i loro inode, è possibile utilizzare la sintassi -o(significato o ) per find:

$ 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

È possibile aggiungere più numeri di inode estendendo l'espressione tra parentesi con più -o -inum <inode_number>espressioni.


4
Che ne dici rm -ri .?
Brent Baccala,

Funzionava: trova <somepath> -inum <inode_number> -exec rm -i {} \; Cosa fanno '-inum', '{}' e '\' nel comando?
Karjedavpalaa,

Come rimuovo più file in una volta sola? Inoltre, grazie, mi hai reso felice!
Karjedavpalaa,

2
@BrentBaccala rm -ri .non sta eliminando i file per inode. Richiederà semplicemente l'intera directory di lavoro e chiederà ogni file se si desidera rimuoverlo - e si deve essere molto attenti ai file richiesti per non rimuovere accidentalmente quelli indesiderati. Non vorrei certo usare questo comando per la mia home directory - contiene MOLTI file. ;)
Malte Skoruppa il

3
@karjedavpalaa (1) -inumdice finddi cercare i file in base al loro numero di inode. (2) {}corrisponde ai file trovati da grep. (3) \ sfugge al ;simbolo che termina il comando passato -execall'opzione di find. (4) Ho modificato la mia risposta per spiegare come rimuovere più file in una volta sola.
Malte Skoruppa,

13

È importante capire che questo non è il tipo di "corruzione del filesystem" che fsckti aiuterà. Per quanto riguarda il filesystem, i nomi dei file possono essere qualsiasi sequenza di byte , purché nessun singolo byte abbia il valore 0x00 (ASCII NUL, C end-of-string marker) o 0x2F ( /, il separatore di directory). (Se un nome di file ottiene in qualche modo un byte 00 o 2F incorporato al suo interno, fsckdovrebbe risolverlo.)

Piuttosto, quello che hai sono i nomi dei file che il software applicativo (Dolphin, ls) pensa contengano caratteri che non sono visualizzabili nella tua "locale", quindi li sta sostituendo con caratteri segnaposto. Non puoi nemmeno digitare quei caratteri, quindi manipolare i file è più difficile, ma puoi farlo fintanto che lo fai senza mai digitare o copiare e incollare il nome. Ad esempio, se elimini o rinomini i file del problema direttamente da Dolphin, dovrebbe funzionare (direi che se non funziona, è un bug in Dolphin).

Se devi fare qualcosa al riguardo dalla shell (ad esempio, se sono di proprietà roote quindi non possono essere modificati da un programma GUI), puoi nominarli indirettamente usando i modelli "glob", che verranno espansi nella sequenza corretta (s) di byte e passati.

Ora, ovviamente, non vorrai cancellare cose per caso perché il tuo modello glob corrispondeva troppo, quindi la mia raccomandazione sarebbe di usare l' renameutilità Perl per convertire ogni nome di file nella sua codifica esadecimale:

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

Questo non distrugge alcuna informazione, né il file stesso, né qualsiasi significato potrebbe essere stato codificato nel nome file prima che venisse modificato. Può essere annullato per file specifici con es

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

Attenzione: esistono due programmi denominati rename, di origini diverse; i comandi sopra funzionano solo con quello che ha origine in Perl. In Ubuntu, quello che vuoi è quello del pacchetto "rinomina", non quello del pacchetto "util-linux". rename -hdistingueremo: questo è quello che vuoi ...

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

... Questo non è quello che vuoi ...

$ rename -h

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

La cosa fondamentale da cercare è "perlexpr". Potresti avere una versione precedente della ridenominazione Perl che non comprende tutte le opzioni sopra, ma il comando che ho mostrato dovrebbe comunque funzionare.

Modifica: Sotto 14.04 .5 lo script perl incluso per renamenon supporta l'opzione -h. Puoi confermare di avere quello corretto controllando la sua pagina man con man renamenel qual caso la prima riga conterrà:

RENAME (1) Guida di riferimento dei programmatori Perl RENAME (1)


rinomina --versione Opzione sconosciuta: versione
Anziano Geek,

@ElderGeek Cosa file $(which rename)stampa? (Assicurati di aver fileinstallato il pacchetto, per prima.)
zwol

/usr/bin/rename: symbolic link to /etc/alternatives/rename( fileè installato di default) In realtà devi inseguire i collegamenti simbolici per ottenere, /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable ma man renameè un'indicazione più rapida ...
Anziano Geek,

@ElderGeek Se è uno script perl, probabilmente è una versione precedente di "quella originata con Perl", che non supporta --version; il comando che ho suggerito dovrebbe ancora funzionare. (/usr/share/doc/rename/changelog.gz sul mio computer, che esegue Debian instabile, indica che è --versionstato aggiunto nella versione 0.10 della ridenominazione Perl, nel 2013. Sono sorpreso che Ubuntu stia ancora spedendo qualcosa di più vecchio di quello, ma questo programma in realtà non ha cambiato la sua funzionalità dal 2007 (!) quindi va bene.)
zwol,

Ah! Questo spiega la confusione. Nonostante molte affermazioni contrarie, Debian non è Ubuntu. Non posso parlare per ogni versione, ma alcune versioni attualmente supportate di Ubuntu LTS (14.04) non lo hanno ancora. (Anche se il 16.04 sì)
Anziano Geek, l'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.