Tidak dapat menghapus / memindahkan file dengan karakter khusus dalam nama file

17

Seperti yang Anda lihat di bawah, file-file tersebut memiliki karakter yang tidak biasa.

tangkapan layar pengelola file

Menghapusnya baik di terminal atau Dolphin mengembalikan kesalahan:

tidak ada berkas atau direktori seperti itu

Berjalan ls -ladi direktori memberi saya output ini:

-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

Saya menjalankan fsckperintah pada partisi dari OS lain tetapi tidak mengubah apa pun.

Bagaimana cara menghapus file-file ini?

karjedavpalaa
sumber
1
Apakah Anda mengatur sistem Anda untuk memiliki direktori home terenkripsi?
dobey
@ Tuhan, aku tidak melakukannya.
karjedavpalaa
5
@Panther Anda salah. Hal ini tidak , dengan sendirinya, merupakan indikasi dari sistem file korup, dan bahkan jika itu disebabkan oleh korupsi data dari beberapa jenis, fsck tidak akan melakukan apa-apa tentang hal itu.
zwol
1
Saya memiliki file dengan karakter yang tidak dikenal dalam namanya. Mengganti nama file berhasil. maka mereka bisa dihapus.
ravery

Jawaban:

35

Cara sederhana adalah menghapus file-file ini dengan inode mereka. :)

Gunakan ls -lidalam direktori dengan karakter yang tidak biasa untuk menunjukkan nomor inode setiap file, misalnya,

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

Selanjutnya, gunakan findutilitas untuk menghapus file yang sesuai dengan namanya, menggunakan sintaks find <somepath> -inum <inode_number> -exec rm -i {} \;, seperti dalam contoh berikut:

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

The -ipilihan untuk rmtidak benar-benar diperlukan, saya hanya menambahkan untuk menjaga Anda dari sengaja menghapus file Anda tidak bermaksud untuk menghapus. :) Itu menyebabkan rmmeminta konfirmasi untuk setiap file yang ingin Anda hapus.

Jika Anda ingin menghapus beberapa file dengan inode mereka, Anda dapat menggunakan sintaks -o(arti atau ) untuk 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

Anda dapat menambahkan lebih banyak nomor inode dengan memperluas ekspresi dalam tanda kurung dengan lebih banyak -o -inum <inode_number>ekspresi.

Malte Skoruppa
sumber
4
Bagaimana dengan rm -ri .?
Brent Baccala
Ini berhasil: find <somepath> -inum <inode_number> -exec rm -i {} \; Apa yang dilakukan '-inum', '{}', dan '\' dalam perintah?
karjedavpalaa
Bagaimana cara menghapus beberapa file sekaligus? Juga, terima kasih, kamu membuat hariku!
karjedavpalaa
2
@BrentBaccala rm -ri .tidak menghapus file dengan inode. Itu hanya akan berulang melalui seluruh direktori kerja dan meminta setiap file jika Anda ingin menghapusnya - dan Anda harus sangat memperhatikan file yang diminta agar tidak secara tidak sengaja menghapus yang tidak diinginkan. Saya tentu tidak ingin menggunakan perintah ini untuk direktori rumah saya - ini berisi BANYAK file. ;)
Malte Skoruppa
3
@karjedavpalaa (1) -inummemberi tahu finduntuk mencari file dengan nomor inode mereka. (2) {}cocok dengan file yang ditemukan oleh grep. (3) \ lolos dari ;simbol yang menghentikan perintah yang diteruskan ke -execopsi find. (4) Saya telah mengedit jawaban saya untuk menjelaskan cara menghapus banyak file sekaligus.
Malte Skoruppa
13

Penting untuk dipahami bahwa ini bukan jenis "korupsi sistem file" yang fsckakan membantu. Sejauh menyangkut filesystem, nama file dapat berupa urutan byte , selama tidak ada byte tunggal yang memiliki nilai 0x00 (ASCII NUL, C end-of-string marker) atau 0x2F ( /, pemisah direktori). (Jika nama file entah bagaimana mendapatkan byte 00 atau 2F tertanam di dalamnya, fsckharus memperbaikinya.)

Alih-alih, yang Anda miliki adalah nama file yang menurut perangkat lunak aplikasi (Dolphin, ls) berisi karakter yang tidak dapat ditampilkan di "lokal" Anda, jadi itu menggantinya dengan karakter placeholder. Anda juga tidak dapat mengetikkan karakter-karakter itu, jadi memanipulasi file lebih sulit, tetapi Anda dapat melakukannya selama Anda melakukannya tanpa pernah mengetik atau menyalin dan menempelkan nama. Sebagai contoh, jika Anda menghapus atau mengganti nama file-file yang bermasalah langsung dari dalam Dolphin, itu seharusnya hanya berfungsi (saya akan mengatakan bahwa jika itu tidak berhasil, itu adalah bug di Dolphin).

Jika Anda perlu melakukan sesuatu tentang mereka dari shell (misalnya, jika mereka dimiliki oleh rootdan oleh karena itu tidak dapat dimodifikasi oleh program GUI), Anda dapat memberi nama mereka secara tidak langsung menggunakan pola "glob", yang akan diperluas ke urutan yang benar (s) dari byte dan diteruskan.

Sekarang, tentu saja, Anda tidak akan ingin menghapus hal-hal secara tidak sengaja karena pola glob Anda terlalu cocok, jadi rekomendasi saya adalah menggunakan renameutilitas Perl untuk mengonversi setiap nama file ke pengkodean hex-nya:

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

Ini tidak menghancurkan informasi apa pun - baik file itu sendiri, maupun makna apa pun yang semula mungkin telah dikodekan dalam nama file sebelum hancur. Dapat dibatalkan untuk file tertentu dengan mis

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

Perhatian: ada dua program bernama rename, dari asal yang berbeda; perintah di atas hanya akan bekerja dengan yang berasal dari Perl. Di Ubuntu, yang Anda inginkan adalah yang dari paket "rename", bukan yang dari paket "util-linux". rename -hakan membedakan: inilah yang Anda inginkan ...

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

... ini bukan yang kamu inginkan ...

$ rename -h

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

Hal utama yang harus dicari adalah "perlexpr". Anda mungkin memiliki versi yang lebih lama dari perubahan nama Perl yang tidak mengerti semua opsi di atas, tetapi perintah yang saya perlihatkan masih tetap berfungsi.

Sunting: Di bawah 14.04 .5 skrip perl yang disertakan untuk renametidak mendukung -h switch. Anda dapat mengonfirmasi bahwa Anda memiliki yang benar dengan memeriksa halaman manualnya man renameyang dalam hal ini baris teratas akan berisi:

RENAME (1) Panduan Referensi Programmer Perl RENAME (1)

zwol
sumber
rename --version Opsi tidak dikenal: versi
Penatua Geek
@ElderGeek Apa yang file $(which rename)dicetak? (Pastikan Anda sudah filemenginstal paketnya.)
zwol
/usr/bin/rename: symbolic link to /etc/alternatives/rename( filesudah terinstal secara default) Sebenarnya Anda harus mengejar tautan simbolik untuk mendapatkannya /usr/bin/file-rename: a /usr/bin/perl -w script, ASCII text executable tetapi man renamemerupakan indikasi yang lebih cepat ...
Penatua Geek
@ElderGeek Jika skrip perl, maka mungkin versi yang lebih lama dari "yang berasal dari Perl", itu tidak mendukung --version; perintah yang saya sarankan harus tetap berfungsi. (/usr/share/doc/rename/changelog.gz di komputer saya, yang menjalankan Debian tidak stabil, menunjukkan bahwa --versiontelah ditambahkan di versi 0.10 dari perubahan nama Perl, pada 2013. Saya terkejut Ubuntu masih mengirimkan sesuatu yang lebih tua dari itu, tetapi program ini belum benar-benar mengubah fungsinya sejak 2007 (!) jadi tidak masalah.)
zwol
Ah! Itu menjelaskan kebingungan. Meskipun banyak klaim sebaliknya, Debian bukan Ubuntu. Saya tidak dapat berbicara untuk setiap rilis, tetapi beberapa versi Ubuntu LTS (14.04) yang saat ini didukung masih belum memilikinya. (Meskipun 16,04 melakukannya)
Penatua Geek