web-dev-qa-db-ja.com

ファイル名のスペース、ハイフン、アンダースコアを削除しますか?

ディレクトリ内のすべてのファイル、または選択したファイルからスペース、ハイフン、アンダースコアを削除するための適切なコマンドは何ですか?

Thunarカスタムアクションで次のコマンドを使用して、ファイル名をスラッグ化します。

for file in %N; do mv "$file" "$(echo "$file" | tr -s ' ' | tr ' A-Z' '-a-z' | tr -s '-' | tr -c '[:alnum:][:cntrl:].' '-')"; done

ただし、このコマンドはスペースをダッシュ​​/ハイフンと小文字の大文字に置き換えるだけです。

ターミナルで次のコマンドを使用して、フォルダー内の何千ものファイル名からスペースを削除しました。

 rename "s/ //g" *

この場合も、スペースのみが削除され、ハイフン/ダッシュやアンダースコアは削除されません。

理想的には、ファイル名にスペース、ハイフン/ダッシュ、アンダースコアを使用したくない。また、選択したファイルのThunarカスタムアクションでコマンドを使用できると便利です。

10
user8547

renameパッケージに付属するPerlのバージョンは、正規表現をサポートしています。

rename "s/[-_ ]//g" *

または、

rename -i "s/[-_ ]//g" *

-iフラグは、renameが対話モードを使用するようにし、ターゲットがすでに存在する場合は、暗黙的に上書きするのではなく、プロンプトを表示します。

Perlの名前変更は、prenameと呼ばれることもあります。

Perlの名前変更とutil-linuxの名前変更

Debianのようなシステムでは、Perlの名前の変更がデフォルトのようであり、上記のコマンドが機能するはずです。

一部のディストリビューションでは、util-linuxのrenameユーティリティがデフォルトです。このユーティリティは、Perlのrenameと完全に互換性がありません。

  • すべて:最初に、Perlのrenameprenameという名前で使用できるかどうかを確認します。

  • Debian:Perlの名前変更をデフォルトにする必要があります。 prenameとしても入手できます。ただし、rename実行可能ファイルは/etc/alternativesの制御下にあるため、別の何かに変更されている可能性があります。

  • archlinux:pacman -S Perl-renameを実行すると、コマンドはPerl-renameとして使用できます。より便利な名前にするには、エイリアスを作成します。 (帽子の先端:ChiseledAbs)

  • Mac OSXこの答え によると、renameはOSXにhomebrewを使用してインストールできます。

    brew install rename 
    
  • 直接ダウンロード:renameはPerl Monksからも入手できます。

     wget 'http://www.perlmonks.org/?displaytype=displaycode;node_id=303814' -O rename
    
11
John1024

私はそれらすべてのtrコマンドをsed置換コマンドに置き換えます。例:

for file in %N; do 
    mv "$file" "$(echo "$file" | sed 's/[ _-]//g')"
done
5

perlを使用している場合は、通常、名前を変更します。できるよ:

> type rename
rename is /usr/bin/rename

このスクリプトの記述方法を示します。

> cat /usr/bin/rename | head -n 5 #firt 5 lines for example
#!/usr/bin/Perl -w
#
#  This script was developed by Robin Barker ([email protected]),
#  from Larry Wall's original script eg/rename from the Perl source.
#

このスクリプトは-iフラグ(これは私のシステムのバージョンです)をサポートしていませんが、おそらくサポートしています。引数についてはどうですか。最初はPCRE形式の正規表現で、フィルターのように機能し、入力名を出力名に変更します。アスタリスク「*」で指定した入力名のリスト。たとえば、次のようにします。

> cd /tmp
> rename 's/ //g' *

実際には「*」は次のように展開できます。

> rename 's/ //g' file1 file2 file3 othe files found in current directory

あなたが本当に大きな数のファイルを持っているとき、あなたは罠にかかっています。シェルはシステムが受け入れるよりも長くあなたのラインを拡張します。その後、findまたはxargsを使用して回避策を実行できます。名前の変更は、ディレクトリ内のファイル数と同じ回数だけ呼び出されるため、「検索」の使用には問題があります。 xargsを-rオプションとともに使用することをお勧めします。 1つの名前変更呼び出しで多くのファイルが変更されます。例えば:

> ls | xargs -r rename 's/ //g'   #thats all, names will be appended at the end of this command.

最後の問題、それはどういう意味ですか:

's/ //g'

これは、名前を変更するための正規表現です。最初の「/」の後はスペースです。これが検出され、2番目の「/」の後の文字列に置き換えられます。ただし、3番目の「/」で終わる空の文字列があり、スペースは何も置き換えられません。オプション「g」は、この表現を繰り返します。式は、最初から最後まですべての名前を検索し、すべてのスペースを検出します。

しかし、タブ文字や他の「白い」文字がある場合はどうでしょうか。この「\ s」に代わるものがあります。他にどのような不要な文字?式に追加するだけです。括弧ですべて閉じます。次に例を示します。

's/[\s_-]//g'

これですべてです。似ていると思いますかman perlrequickとman perlretutを読むべきだと思います。これは、正規表現がどのように機能するかを説明します(私はそう思います)。必要に応じて、独自のスクリプトでrenameコマンドを使用できます。

2
Znik

次のshシェルループは、既存のファイルを上書きしないように注意して、現在のディレクトリのファイル名からすべてのスペース、アンダースコア、ダッシュを削除します。

for f in *; do
    test -f "$f" || continue
    nf=$( echo "$f" | tr -d ' _-' )
    ! test -e "$nf" && echo mv "$f" "$nf"
done

bashおよびkshの場合、ロジックを少し冗長にします。

for f in *; do
    if [[ -f "$f" ]]; then
        nf=$( tr -d ' _-' <<<"$f" )
        if [[ ! -e "$nf" ]]; then
            echo mv "$f" "$nf"
        fi
    fi
done

echoを削除します。意図したとおりに機能することが確実な場合は削除してください。

trコマンドは(-d)指定された文字セットの任意の文字(' _-')。セットの最初または最後にダッシュを置くことが重要です。そうしないと、一連の文字として解釈されます。

1
Kusalananda