ファイル名から無効な文字を削除する方法は?


47

これらのような無効な文字を含むファイルがあります

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

Æファイル名のどこかで問題が発生した場所です。

無効な文字をすべて削除する方法はありますか?

またはtr何とか使用できますか?

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

5
文字はおそらく「無効」ではありません。それ以外の場合、ファイルシステムはそれらを格納しません(FSに対して本当に厄介なことをしない限り)。名前を正しく表示するためにロケールを(UTF8などに)変更しようとしましたか?
ジェームズオゴーマン

回答:


41

1つの方法はsedを使用することです。

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

fileもちろん、ファイル名に置き換えてください。これにより、文字、数字、ピリオド、アンダースコア、ダッシュ以外のものはすべてアンダースコアに置き換えられます。好きなように文字を追加または削除したり、置換文字を他の文字に変更したり、まったく変更したりすることはできません。


4
私が使用したもの:f='file'; mv 'file' ${f//[^A-Za-z0-9._-]/_}
ルイ

1
以下H.ヘスによって最善の解決策を探し...(と一緒に:)私の面白いコメント)
ヤンシラ

31

Linuxボックスを使用しており、ファイルはWindowsボックスで作成されていると思います。Linuxはファイル名の文字エンコードとしてUTF-8を使用しますが、Windowsは他のものを使用します。これが問題の原因だと思います。

「convmv」を使用します。これは、ファイル名をある文字エンコーディングから別のエンコーディングに変換できるツールです。西ヨーロッパでは、次のいずれかが通常機能します。

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 .

DebianベースのLinuxにインストールする必要がある場合は、次を実行してインストールできます。

sudo apt-get install convmv

それは私のために毎回動作し、元のファイル名を回復します。

ソース:LeaseWebLabs


1
これは有望に見えますが、エンコーディングが何であるかを知る方法はありますか?Save the current file in Word 97-2004 format\sco.workflowMacで(Microsoft Office経由で)作成されたというディレクトリがあり、上記のエンコーディングは効果がありません。
スリダールサルノバト16

デフォルトでは、convmvは「テスト」モードで実行されます。このモードでは、ドライランが実行され、移動するファイルが通知されます。次に--notest、実際にファイルの名前を変更するオプションを使用して、もう一度実行するように指示されます。
ケニーラッシャート

16

ファイルシステムを走査して、そのようなファイルをすべて修正したいということですか?

これが私がやる方法です

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

これは、非ASCII文字を持つすべてのファイルを検索し、それらの文字をアンダースコア(_)に置き換えます。ただし、新しい名前のファイルが既に存在する場合は上書きされるため、注意してください。このようなケースをチェックするためにスクリプトを変更できますが、単純にするためにそれを入れませんでした。


13

https://stackoverflow.com/questions/2124010/grep-regex-to-match-non-ascii-charactersの回答に従って、次を使用できます:

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

where *は、名前を変更するファイルと一致します。複数のディレクトリで実行したい場合、次のようなことができます:

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

-n引数を使用renameして予行演習を行い、変更せずに何が変更されるかを確認できます。


これを変更して、たとえばüやäなどの外部文字を保持する方法はありますか?
オタク長老

私にとっては2番目のものだけが働いた。すべてが同じディレクトリにあったので、何が違うのか分かりません。
ショーティー

1
@Shautieh:-nは、実際の実行を停止します。答えを明確にします。
-naught101

多くのファイルを処理する場合、名前の変更が遅くなる可能性があります。これをスピードアップしたい場合は、チェックを押して検索します。しかし、私はそれを行う方法がわかりません。
isaaclw

13

壊れたusbスティックからファイル名が壊れた日本語ファイルをいくつか復元しましたが、上記の解決策はうまくいきませんでした。

デトックスパッケージをお勧めします。

detoxユーティリティは、ファイルの名前を変更して作業しやすくします。スペースやその他の迷惑な要素を取り除きます。また、8ビットASCIIでエンコードされたLatin-1(ISO 8859-1)文字、UTF-8でエンコードされたUnicode文字、およびCGIエスケープ文字も変換またはクリーンアップします。

使用例:

detox -r -v /path/to/your/files
-rサブディレクトリへの再帰
-vどのファイルの名前が変更されているかを詳細に示します 
-n予行演習に使用できます(変更内容のみを表示)

2
これはもっと高くなければならない、私は誰もがdetox本質的に車輪を再発明する前に一見することを勧める。マニュアルページを見ると、その柔軟性のために、ここで提案されている他のすべてのソリューションを網羅していることがわかります。
emk2203

エゼキエル25:17-慈善と善意の名において、この解決策を支持する人は祝福されます。
ヤンシラ

直感的には、パスを「。」にすることはできません debianで。「。」を使用する場合 何も見つかりません。
isaaclw

本当に機能するのか、たとえば漢字を削除/置換するように思え的节奏啊ますが、これらの文字は有効なファイル名です。
林果皞

5

このシェルスクリプトは、ディレクトリを再帰的に無害化し、Linux / WindowsとFAT / NTFS / exFATの間でファイルを移植できるようにします。制御文字と、/:*?"<>\|などの予約済みのWindows名を削除し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'

Linuxは、理論的には制約が少ない(/\0厳密にファイル名に禁止されています)が、実際にいくつかの文字は、bashのコマンド(のように干渉し*、彼らはまた、ファイル名に避けなければならないので...)。

ファイルの命名制限に関する優れた情報源:


1
それは私が検索するものです!ただし、スペースを含むディレクトリをサポートするために引用符を追加します。「$ 1」を検索します-depth -exec bash -c 'sanitize "$ 0"' {} \;
mmv-ru

1

埋め込まれた改行、マルチバイト文字、スペース、先頭のダッシュ、バックスラッシュ、およびより堅牢なものが必要になるスペースを処理する場合は、この回答を参照してください:https :
//superuser.com/a/858671/365691

誰かが興味を持っている場合は、code.google.comにスクリプトを配置します:rnf-bash-rename-script


ここにリンクされたスクリプトは私のために問題を解決しました
ジェレマイアローズ

0

このワンライナーを使用して、字幕ファイル内の無効な文字を削除します。

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. * .srtファイルのみを処理します(* .srtの代わりに*を使用して、すべてのファイルを処理できます)
  2. 文字A〜Z、A〜Z、数字0〜9、ピリオド「。」、およびダッシュの「-」以外のすべての文字を削除します。
  3. 考えられる二重または三重の期間を削除します
  4. ファイル名を変更する必要があるかどうかを確認します
  5. trueの場合、mvコマンドでファイルの名前を変更し、echoコマンドで行った変更を出力します

映画のディレクトリ名を正規化するために機能します:

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

上記と同じ手順ですが、ディレクトリの最後のピリオドを削除するためにもう1つのsedコマンドを追加しました

X-Men Days of Future Past(2014)[1080p]
変更後:
X-Men.Days.of.Future.Past.2014.1080p


-2

*のファイル用 do mv "$ file" $(echo "$ file" | sed -e 's / [^ A-Za-z0-9。- ] / / g'); 完了


2
コードの機能を説明し、適切なフォーマットを使用する必要があります。コードに名前の衝突が発生することにより、ファイルが削除される可能性があります。そして、すべてをバックグラウンドで実行するのは、ちょっと馬鹿げています。
カスペルド
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.