Saya memiliki banyak direktori dan subdirektori yang berisi file dengan karakter khusus, seperti file ini:
robbie@phil:~$ ls test�sktest.txt
test?sktest.txt
Temukan mengungkapkan urutan pelarian:
robbie@phil:~$ find test�sktest.txt -ls
424512 4000 -rwxr--r-x 1 robbie robbie 4091743 Jan 26 00:34 test\323sktest.txt
Satu-satunya alasan saya bahkan dapat mengetik nama mereka di konsol adalah karena penyelesaian tab. Ini juga berarti saya dapat mengganti nama secara manual (dan menghapus karakter khusus).
Saya telah mengatur LC_ALL ke UTF-8, yang sepertinya tidak membantu (juga tidak pada shell baru):
robbie@phil:~$ echo $LC_ALL
en_US.UTF-8
Saya terhubung ke mesin menggunakan ssh dari mac saya. Ini adalah instalasi Ubuntu:
robbie@phil:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=7.10
DISTRIB_CODENAME=gutsy
DISTRIB_DESCRIPTION="Ubuntu 7.10"
Shell adalah Bash, JANGKA diatur ke warna xterm.
File-file ini telah ada di sana cukup lama, dan mereka belum dibuat menggunakan instalasi Ubuntu itu. Jadi saya tidak tahu apa pengaturan sistem pengkodean dulu.
Saya sudah mencoba beberapa hal di sepanjang baris:
find . -type f -ls | sed 's/[^a-zA-Z0-9]//g'
Tetapi saya tidak dapat menemukan solusi yang melakukan semua yang saya inginkan:
- Identifikasi semua file yang memiliki karakter yang tidak dapat diputar (terlalu banyak mengabaikan hal di atas)
- Untuk semua file di pohon direktori (secara rekursif), jalankan mv oldname newname
- Secara opsional, kemampuan untuk mentransliterasi karakter khusus seperti ä ke (tidak diperlukan, tetapi akan luar biasa)
ATAU
- Tampilkan semua file ini dengan benar (dan tidak ada kesalahan dalam aplikasi saat mencoba membukanya)
Saya punya bit dan potongan, seperti iterasi semua file dan memindahkannya, tetapi mengidentifikasi file dan memformatnya dengan benar untuk perintah mv tampaknya menjadi bagian yang sulit.
Setiap informasi tambahan tentang mengapa mereka tidak ditampilkan dengan benar, atau bagaimana "menebak" pengkodean yang benar juga diterima. (Saya sudah mencoba convmv tetapi sepertinya tidak melakukan apa yang saya inginkan: http://j3e.de/linux/convmv/ )
Jawaban:
Saya kira Anda melihat
�
karakter yang tidak valid ini karena namanya berisi urutan byte yang tidak valid UTF-8. Nama file pada sistem file unix yang khas (termasuk milik Anda) adalah string byte, dan tergantung pada aplikasi untuk memutuskan encoding apa yang akan digunakan. Saat ini, ada kecenderungan untuk menggunakan UTF-8, tetapi itu tidak universal, terutama di lokal yang tidak pernah bisa hidup dengan ASCII biasa dan telah menggunakan pengkodean lain sejak sebelum UTF-8 bahkan ada.Cobalah
LC_CTYPE=en_US.iso88591 ls
untuk melihat apakah nama file masuk akal di ISO-8859-1 (latin-1). Jika tidak, coba tempat lain. Perhatikan bahwa hanyaLC_CTYPE
pengaturan lokal yang penting di sini.Di lokal UTF-8, perintah berikut akan menampilkan semua file yang namanya tidak valid UTF-8:
Anda dapat memeriksa apakah mereka lebih masuk akal di lokal lain dengan recode atau iconv :
Setelah Anda menentukan bahwa sekelompok nama file berada dalam pengkodean tertentu (misalnya latin1), salah satu cara untuk menamainya adalah
Ini menggunakan perintah perl rename yang tersedia di Debian dan Ubuntu. Anda dapat meneruskannya
-n
untuk menunjukkan apa yang akan dilakukan tanpa benar-benar mengganti nama file.sumber
grep [^[:print:]]
mencari karakter yang tidak patut. Tapi saya baru saja diuji dengan GNU grep dan urutan UTF-8 tidak valid tidak tertangkap[^[:print:]]
(yang masuk akal karena mereka bukan karakter yang tidak patut, mereka bukan karakter sama sekali). Saya telah mengedit posting saya dengan cara yang lebih lama dalam menangkap garis dengan urutan utf8 yang tidak valid. Perhatikan bahwa saya juga telah memperbaiki arahrecode
daniconv
contoh.Saya tahu ini adalah pertanyaan lama tetapi saya telah mencari sepanjang malam untuk solusi yang sama. Saya menemukan beberapa tips bermanfaat tetapi mereka tidak melakukan apa yang saya butuhkan, jadi saya harus mencampur dan mencocokkan beberapa untuk mendapatkan hasil yang benar yang saya cari
untuk hanya menghapus karakter khusus dan menggantinya dengan tanda (.)
untuk digunakan dalam cronjob, saya melakukan yang berikut untuk menjalankan setiap menit
Saya harap seseorang menemukan ini bermanfaat karena telah membuat hari saya :)
sumber
`…`
untuk$(…)
- melihat ini , ini , dan ini . (2) Anda harus selalu mengutip referensi variabel shell Anda (misalnya,"$f"
) kecuali Anda memiliki alasan yang baik untuk tidak melakukannya, dan Anda yakin Anda tahu apa yang Anda lakukan. Ini berlaku bahkan untukecho "$f" | sed …
. Ini juga berlaku untuk seluruh$(…)
(atau`…`
) ekspresi; yaitumv "$f" "$(echo "$f" | sed "…")"
,. … (Lanjutan)mv
--
"$f" …
-
Sekarang, ketika Anda tahu pengkodean mana yang digunakan untuk nama file pada ujung jarak jauh ("latin1" - sesuai dengan komentar pada jawaban pertama), Anda juga dapat mengikuti cara kedua - jalankan termninal lokal dan ssh sedemikian rupa cara nama file jarak jauh ditampilkan dengan benar (daripada cara pertama: ganti nama mereka) .
Seperti saya , Anda dapat memulai terminal secara lokal yang akan berfungsi dalam pengkodean khusus itu, mungkin, seperti ini:
LC_ALL = en_US.latin1 xvt &
xvt
singkatan dari program terminal Anda.Mungkin, lokal yang ada disebut
en_US.iso88591
, dan tidaken_US.latin1
, seperti yang saya duga.sumber
Ini tidak memenuhi persyaratan massal, tetapi saya baru saja mengalami masalah yang sama di mana saya memiliki beberapa versi file dengan nama yang sama yang hanya berbeda oleh satu karakter aneh. Sayangnya ini berarti bahwa saya tidak dapat mengganti nama pelanggar menggunakan trik wildcard yang biasa saya gunakan.
Pada akhirnya saya menggunakan Filezilla untuk terhubung sebagai klien SFTP, melihat-lihat file dan menamainya menggunakan GUI. Filezilla menangani karakter cerdik dengan cukup baik.
sumber