Nie można usunąć / przenieść plików ze znakami specjalnymi w nazwie pliku

17

Jak widać poniżej, pliki mają nietypowe znaki.

zrzut ekranu menedżera plików

Usunięcie ich w terminalu lub Dolphin zwraca błąd:

Brak takiego pliku lub katalogu

Uruchomienie ls -lakatalogu dało mi ten wynik:

-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

Uruchomiłem fsckpolecenie na partycji z innego systemu operacyjnego, ale nic to nie zmieniło.

Jak mogę usunąć te pliki?

karjedavpalaa
źródło
1
Czy skonfigurowałeś swój system, aby mieć zaszyfrowany katalog domowy?
dobey,
@dobey Nie zrobiłem.
karjedavpalaa
5
@Panther Mylisz się. Nie jest to samo w sobie oznaką uszkodzenia systemu plików i nawet jeśli było to spowodowane jakimś uszkodzeniem danych, fsck nic z tym nie zrobi.
zwolnienie
1
W nazwie miałem pliki z nierozpoznanymi postaciami. Zmiana nazw plików zadziałała. wtedy mogą zostać usunięte.
pustkowie

Odpowiedzi:

35

Prostym sposobem byłoby usunięcie tych plików według ich i-węzłów. :)

Użyj ls -liw katalogu z nietypowymi znakami, aby wyświetlić numer i-węzła każdego pliku, np.

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

Następnie użyj findnarzędzia, aby usunąć odpowiedni plik według jego nazwy, używając składni find <somepath> -inum <inode_number> -exec rm -i {} \;, jak w poniższym przykładzie:

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

-iOpcja rmnie jest to naprawdę konieczne, po prostu dodaje się do siebie przed przypadkowym usuwania plików nie chciałem usunąć. :) Powoduje rmprośbę o potwierdzenie dla każdego pliku, który chcesz usunąć.

Jeśli chcesz usunąć wiele plików według ich i-węzłów, możesz użyć składni -o(znaczenia lub ) dla 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

Możesz dodać więcej numerów i-węzłów, rozszerzając wyrażenie w nawiasach o więcej -o -inum <inode_number>wyrażeń.

Malte Skoruppa
źródło
4
Jak o rm -ri .?
Brent Baccala,
Działa to: znajdź <somepath> -inum <nod_number> -exec rm -i {} \; Co robi polecenie „-inum”, „{}” i „\” w poleceniu?
karjedavpalaa
Jak usunąć wiele plików za jednym razem? Również dziękuję, że sprawiłeś, że mój dzień!
karjedavpalaa
2
@BrentBaccala rm -ri .nie usuwa jednak plików według i-węzła. Po prostu przejdzie przez cały katalog roboczy i poprosi o każdy plik, jeśli chcesz go usunąć - i musisz bardzo uważnie wybierać pliki, o które prosi, aby nie przypadkowo usunąć niechcianych plików. Na pewno nie chciałbym używać tego polecenia do mojego katalogu domowego - zawiera DUŻO plików. ;)
Malte Skoruppa
3
@karjedavpalaa (1) -inumkaże findszukać plików według ich numeru i-węzła. (2) {}odpowiada plikowi znalezionemu przez grep. (3) \ ucieka ;symbolowi, który kończy polecenie przekazane do -execopcji find. (4) Zredagowałem swoją odpowiedź, aby wyjaśnić, jak usunąć wiele plików za jednym razem.
Malte Skoruppa
13

Ważne jest, aby zrozumieć, że nie jest to rodzaj „uszkodzenia systemu plików”, fsckktóry pomoże. Jeśli chodzi o system plików, nazwy plików mogą być dowolną sekwencją bajtów , o ile żaden pojedynczy bajt nie ma wartości 0x00 (ASCII NUL, znacznik końca łańcucha C) lub 0x2F ( /separator katalogu). (Jeśli nazwa pliku ma wbudowany bajt 00 lub 2F, fsckpowinna to naprawić).

Zamiast tego mamy nazwy plików, które według oprogramowania (Dolphin ls) zawierają znaki, których nie można wyświetlić w „ustawieniach regionalnych”, dlatego zastępuje je znakami zastępczymi. Nie możesz również wpisywać tych znaków, więc manipulowanie plikami jest trudniejsze, ale możesz to robić tak długo, jak to robisz, bez wpisywania, kopiowania i wklejania nazwy. Na przykład, jeśli usuniesz lub zmienisz nazwę plików problemów bezpośrednio z Dolphin, powinno to po prostu działać (posunąłbym się do stwierdzenia, że ​​jeśli to nie działa, to jest błąd w Dolphin).

Jeśli musisz coś z nimi zrobić z powłoki (na przykład, jeśli są one własnością rooti dlatego nie mogą być modyfikowane przez program GUI), możesz nazwać je pośrednio za pomocą wzorców „glob”, które zostaną rozwinięte do prawidłowej sekwencji (s) bajtów i przekazywane dalej.

Teraz oczywiście nie chcesz przypadkowo usuwać elementów, ponieważ wzorzec globu jest zbyt dopasowany, dlatego zalecam użycie renamenarzędzia Perl do konwersji każdej nazwy pliku na kodowanie szesnastkowe:

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

Nie niszczy to żadnych informacji - ani sam plik, ani jakiekolwiek znaczenie mogło być pierwotnie zakodowane w nazwie pliku, zanim zostanie on zniekształcony. Można go cofnąć dla określonych plików za pomocą np

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

Uwaga: istnieją dwa programy o renameróżnych nazwach ; powyższe polecenia będą działać tylko z tym, które pochodzi z Perla. W Ubuntu ten, którego potrzebujesz, to ten z pakietu „zmień nazwę”, a nie ten z pakietu „util-linux”. rename -hrozróżni: to jest to, czego chcesz ...

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

... nie tego chcesz ...

$ rename -h

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

Kluczową sprawą jest „perlexpr”. Być może masz starszą wersję zmiany nazwy Perla, która nie rozumie wszystkich powyższych opcji, ale polecenie, które pokazałem, powinno nadal działać.

Edycja: poniżej 14.04 .5 dołączony skrypt perla renamenie obsługuje przełącznika -h. Możesz potwierdzić, że masz poprawny, sprawdzając stronę man renamepodręcznika, w którym to przypadku górna linia będzie zawierać:

RENAME (1) Przewodnik dla programistów Perla RENAME (1)

zwol
źródło
zmień nazwę --wersja Nieznana opcja: wersja
Starszy Geek
@ElderGeek Co file $(which rename)drukuje? ( fileNajpierw upewnij się, że masz zainstalowany pakiet).
zwolnij
/usr/bin/rename: symbolic link to /etc/alternatives/rename( filejest instalowany domyślnie) Właściwie musisz gonić za symbolicznymi linkami, aby uzyskać, /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable ale man renamejest to szybsze wskazanie ...
Starszy Geek
@ElderGeek Jeśli jest to skrypt perla, to prawdopodobnie jest to starsza wersja „tego, który pochodzi z Perla”, który nie obsługuje --version; polecenie, które zasugerowałem, powinno nadal działać. (/usr/share/doc/rename/changelog.gz na moim komputerze, na którym działa Debian niestabilny, wskazuje, że --versionzostał dodany w wersji 0.10 zmiany nazwy Perla w 2013 roku. Dziwię się, że Ubuntu wciąż dostarcza coś starszego niż to, ale ten program tak naprawdę nie zmienił swojej funkcjonalności od 2007 roku (!), więc jest w porządku.)
zwolnij
Ach! To wyjaśnia zamieszanie. Pomimo wielu twierdzeń, że jest inaczej, Debian nie jest Ubuntu. Nie mogę mówić w każdej wersji, ale niektóre obecnie obsługiwane wersje Ubuntu LTS (14.04) wciąż tego nie mają. (Chociaż robi to 16.04)
Starszy Geek