Bagaimana cara menghapus karakter yang tidak valid dari nama file?


47

Saya memiliki file dengan karakter yang tidak valid seperti ini

009_-_�%86ndringshåndtering.html

Ini adalah di Æmana ada yang salah dalam nama file.

Apakah ada cara untuk menghapus semua karakter yang tidak valid?

atau bisa trdigunakan entah bagaimana?

echo "009_-_�%86ndringshåndtering.html" | tr ???

5
Karakter mungkin tidak "valid", yang lain filesystem tidak akan menyimpannya (kecuali jika Anda melakukan sesuatu yang benar-benar jahat untuk FS). Sudahkah Anda mencoba mengubah lokal Anda (misalnya menjadi UTF8) untuk menampilkan nama-nama dengan benar?
James O'Gorman

Jawaban:


41

Salah satu caranya adalah dengan sed:

mv 'file' $(echo 'file' | sed -e 's/[^A-Za-z0-9._-]/_/g')

Ganti filedengan nama file Anda, tentu saja. Ini akan menggantikan apa pun yang bukan huruf, angka, titik, garis bawah, atau tanda garis dengan garis bawah. Anda dapat menambah atau menghapus karakter agar tetap sesuai keinginan, dan / atau mengubah karakter pengganti menjadi hal lain, atau tidak sama sekali.


4
Saya menggunakan:f='file'; mv 'file' ${f//[^A-Za-z0-9._-]/_}
Louis

1
Cari solusi terbaik oleh H. Hess di bawah ini ... (dan komentar lucu saya bersama :))
Jan Sila

31

Saya berasumsi Anda berada di kotak Linux dan file dibuat di kotak Windows. Linux menggunakan UTF-8 sebagai pengkodean karakter untuk nama file, sedangkan Windows menggunakan sesuatu yang lain. Saya pikir ini adalah penyebab masalahnya.

Saya akan menggunakan "convmv". Ini adalah alat yang dapat mengonversi nama file dari satu pengkodean karakter ke karakter lain. Untuk Eropa Barat salah satu dari ini biasanya berfungsi:

convmv -r -f windows-1252 -t UTF-8 .
convmv -r -f ISO-8859-1 -t UTF-8 .
convmv -r -f cp-850 -t UTF-8 .

Jika Anda perlu menginstalnya di Linux berbasis Debian Anda dapat melakukannya dengan menjalankan:

sudo apt-get install convmv

Ini bekerja untuk saya setiap waktu dan memulihkan nama file asli.

Sumber: LeaseWebLabs


1
ini terlihat menjanjikan, tetapi ada ide bagaimana mengetahui apa pengkodean itu? Saya memiliki direktori yang dipanggil Save the current file in Word 97-2004 format\sco.workflowyang dibuat di Mac saya (via Microsoft Office) dan penyandian di atas tidak berpengaruh.
Sridhar Sarnobat

Perlu disebutkan bahwa secara default convmv berjalan dalam mode "test", di mana ia hanya menjalankan proses kering dan memberi tahu Anda file mana yang akan dipindahkan. Ini kemudian akan memberitahu Anda untuk menjalankannya lagi dengan --notestopsi untuk benar-benar mengganti nama file.
Kenny Rasschaert

16

Saya berasumsi Anda bermaksud ingin melintasi sistem file dan memperbaiki semua file tersebut?

Begini cara saya akan melakukannya

find /path/to/files -type f -print0 | \
perl -n0e '$new = $_; if($new =~ s/[^[:ascii:]]/_/g) {
  print("Renaming $_ to $new\n"); rename($_, $new);
}'

Itu akan menemukan semua file dengan karakter non-ascii dan mengganti karakter tersebut dengan garis bawah ( _). Berhati-hatilah, jika file dengan nama baru sudah ada, itu akan menimpanya. Script dapat dimodifikasi untuk memeriksa kasus seperti itu, tetapi saya tidak memasukkannya agar tetap sederhana.


13

Mengikuti jawaban di https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-characters , Anda dapat menggunakan:

rename 's/[^\x00-\x7F]//g' *

di mana *cocok dengan file yang ingin Anda ganti namanya. Jika Anda ingin melakukannya di banyak direktori, Anda dapat melakukan sesuatu seperti:

find . -exec rename 's/[^\x00-\x7F]//g' "{}" \;

Anda bisa menggunakan argumen -n renameuntuk melakukan dry run, dan melihat apa yang akan diubah, tanpa mengubahnya.


Apakah ada cara untuk memodifikasi ini untuk menjaga karakter asing seperti ü dan ä misalnya?
Penatua Geek

Hanya yang kedua yang bekerja untuk saya. Semuanya ada di direktori yang sama jadi saya tidak yakin apa bedanya ..?
Shautieh

1
@ Shautieh: -n menghentikannya dari benar-benar berjalan. Saya akan mengklarifikasi jawabannya.
naught101

mengganti nama bisa lambat ketika berurusan dengan banyak file. Jika Anda ingin mempercepat ini, dorong tanda centang ke find. Saya tidak yakin bagaimana melakukan itu.
isaaclw

13

Saya punya beberapa file jepang dengan nama file yang rusak pulih dari usb stick yang rusak dan solusi di atas tidak bekerja untuk saya.

Saya merekomendasikan paket detox:

Utilitas detox mengubah nama file agar lebih mudah digunakan. Ini menghilangkan spasi dan gangguan lainnya. Itu juga akan menerjemahkan atau membersihkan karakter Latin-1 (ISO 8859-1) yang dikodekan dalam ASCII 8-bit, karakter Unicode yang dikodekan dalam UTF-8, dan karakter yang lolos CGI.

Contoh penggunaan:

detox -r -v /path/to/your/files
-r Recurse ke dalam subdirektori
-v Bersikap tegas tentang file mana yang sedang diganti namanya 
-n Dapat digunakan untuk lari kering (hanya menunjukkan apa yang akan diubah)

2
Ini harusnya jauh lebih tinggi, saya mendorong semua orang untuk melihat detoxsebelum pada dasarnya menciptakan kembali roda. Jika Anda melihat halaman manual, Anda akan melihat bahwa itu mencakup semua solusi yang diusulkan di sini karena fleksibilitasnya.
emk2203

Yehezkiel 25:17 - Diberkatilah dia yang, atas nama kasih amal dan kebaikan akan memperbaiki solusi ini, karena dia benar-benar penjaga saudaranya dan penemu anak-anak yang hilang.
Jan Sila

Secara tidak sengaja, jalan tidak bisa '.' dalam bahasa debian. Jika Anda menggunakan '.' tidak menemukan apa pun.
isaaclw

Saya bertanya-tanya apakah itu benar-benar berfungsi, sepertinya menghapus / mengganti karakter Cina, misalnya 的节奏啊, tetapi karakter tersebut adalah nama file yang valid.
林果 皞

5

Script shell ini membersihkan direktori secara rekursif, untuk membuat file portable antara Linux / Windows dan FAT / NTFS / exFAT. Ini menghapus karakter kontrol, /:*?"<>\|dan beberapa nama Windows yang dicadangkan suka COM0.

sanitize() {
  shopt -s extglob;

  filename=$(basename "$1")
  directory=$(dirname "$1")

  filename_clean=$(echo "$filename" | sed -e 's/[\\/:\*\?"<>\|\x01-\x1F\x7F]//g' -e 's/^\(nul\|prn\|con\|lpt[0-9]\|com[0-9]\|aux\)\(\.\|$\)//i' -e 's/^\.*$//' -e 's/^$/NONAME/')

  if (test "$filename" != "$filename_clean")
  then
    mv -v "$1" "$directory/$filename_clean"
  fi
}

export -f sanitize

sanitize_dir() {
  find "$1" -depth -exec bash -c 'sanitize "$0"' {} \;
}

sanitize_dir '/path/to/somewhere'

Secara teori Linux tidak terlalu membatasi ( /dan \0dilarang keras dalam nama file) tetapi dalam praktiknya beberapa karakter mengganggu perintah bash (seperti *...) sehingga mereka juga harus dihindari dalam nama file.

Sumber hebat untuk pembatasan penamaan file:


1
Itu yang saya cari! tetapi tambahkan kutipan untuk mendukung dir dengan spasi temukan "$ 1" -depth -exec bash -c 'bersihkan "$ 0"' {} \;
mmv-ru


0

Saya menggunakan satu-baris ini untuk menghapus karakter yang tidak valid dalam file subtitle:

for f in *.srt; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.-]/./g;s/\.\.\././g;s/\.\././g'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done
  1. Hanya memproses file * .srt (* dapat digunakan sebagai pengganti * .srt untuk memproses setiap file)
  2. Menghapus semua karakter lain kecuali huruf A-Za-z, angka 0-9, titik ".", Dan tanda hubung "-"
  3. Menghapus kemungkinan periode dua atau tiga
  4. Cek untuk melihat apakah nama file perlu diubah
  5. Jika benar, ia mengganti nama file dengan perintah mv, kemudian menampilkan perubahan yang dibuatnya dengan perintah echo

Ini berfungsi untuk menormalkan nama direktori film:

for f in */; do nf=$(echo "$f" |sed -e 's/[^A-Za-z0-9.]/./g' -e 's/\.\.\././g' -e 's/\.\././g' -e 's/\.*$//'); test "$f" != "$nf" && mv "$f" "$nf" && echo "$nf"; done

Langkah-langkah yang sama seperti di atas, tetapi saya menambahkan satu perintah sed lagi untuk menghapus periode di akhir direktori

X-Men Days of Future Past (2014) [1080p]
Dimodifikasi ke:
X-Men.Days.of.Future.Past.2014.1080p


-2

untuk file dalam *; lakukan mv "$ file" $ (echo "$ file" | sed -e 's / [^ A-Za-z0-9. -] / / g'); Selesai &


2
Anda harus menjelaskan apa yang kode Anda lakukan dan menggunakan pemformatan yang tepat. Kode Anda dapat menyebabkan file dihapus dengan memperkenalkan collision dalam nama. Dan menjalankan seluruh hal di latar belakang agak konyol.
kasperd
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.