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

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

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

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 カスタム操作で使用できればよいでしょう。

答え1

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

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

または、

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

この-iフラグは、rename対話モードを使用してターゲットを自動的に上書きするのではなく、ターゲットがすでに存在するかどうかを尋ねるメッセージを表示します。

Perlの名前変更は時々と呼ばれますprename

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

Perlの名前変更がデフォルトのDebianシリーズシステムでは、上記のコマンドが機能します。

一部のディストリビューションでは、renameutil-linux のユーティリティがデフォルトです。このユーティリティはPerlのrename

  • すべて:まず、Perlrename名が利用可能であることを確認してくださいprename

  • ダーバン:Perlの名前変更はデフォルト値でなければなりません。としても機能しますprename。ただし、実行可能ファイルがrename制御されるため、/etc/alternatives他のものに変更することができます。

  • Arch Linux:Runを実行するpacman -S perl-renameと、コマンドがで始まりますperl-rename。より便利な名前を使用するには、エイリアスを作成してください。 (帽子のヒント: ChiseledAbs)

  • アップルコンピュータ~によるとこの回答rename以下を使用してhomebrewを使用してOSXにインストールできます。

    brew install rename 
    
  • ダウンロード: renamePerl Monksは以下も提供しています:

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

答え2

trこれらすべてのコマンドを次の代替コマンドに置き換えますsed

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

答え3

いいえmv、実際には外部プロセスはまったく必要ありません。パフそれらを。

ifsqz() ( LC_ALL=C sqz=$1
    isf() { [ -e "$1" ] || [ -L "$1" ] ; }  
    set -- * ; set -f
    for f do isf "$f" || break
    IFS=$sqz; set -- $f; IFS=
    isf "$*" || mv -- "$f" "$*"
    done
)

それでも、これはmvファイルごとに一度呼び出す必要があるという意味なので、おそらくrenameより良いでしょう。これはPOSIX mvin$PATHおよびPOSIXシェルの場合にのみ機能します。

それで私はこれについてのクレイジーなデモを思い出しました。テストセットは次のように生成されます。

tee - - - - <<CGEN |\
dd cbs=90 conv=unblock |\
sed 'G;$!N'";s/^/touch -- '/;s/$/'/" |sh
$( #BEGIN CGEN
   LC_ALL=C
   i= n='"$((i=((i=i+1)==10||i==39||i==47)>0?(i+1):i))"'
   printf '%b -_   ---___'  $(
   IFS=0; eval \
       printf '"\\\\%04o\\\\%04o "' "$(
       printf "$n"' "$i" '%s $(
       printf %.252d
#END
))"))
CGEN

まず、上記のコマンドが他の方法で簡単に得られる結果を生成することをまず認めます。しかし、他のアプローチは、$IFSいくつかの努力で何ができるかを示すのには適していないかもしれません。(病気?)想像力。

したがって、最初のポイントは非常に簡単です。

  • tee入力の5つのコピーをパイプに出力します。ここでは、以下を呼び出します。CGEN

  • dd90バイトブロックあたりの改行文字で入力をブロックし、次にパイプします。

  • sedチャンクの2つを2つの\newline文字で連結し、'結果を一重引用符で囲み、touch --出力をパイピングする前に各行ループの文字列の前に追加します。

  • sh次に、すべての入力をシェルコマンドで実行します。

#CGENところで…まあ、簡単に言えば…

  • 下部にprintf252個のゼロを印刷します。

  • 2番目のエントリは252個の空の文字列パラメータを受け取り、各パラメータに対して次の文字列''の内容を印刷します。$n" $i "

  • eval次のprintf引数を解釈し、2つのバックスラッシュが前にある8進数で解釈結果を印刷します。

  • 最後に、この8進数2のバイト値を印刷してから、各ペアのprintf文字列を印刷します。-_ ---___

  • $n式で初期化され評価される$iたびに 1 を追加しますが、値 10、39、または 47 をスキップします。(ASCII 10\n進改行、'一重引用符、スラッシュのそれぞれ)/

最終結果は、私の文字セット(一重引用符を除く)の1から255までのすべてのバイトを含む非常に見苦しいファイル名を含むディレクトリです。(他の説明を避けるためにただsed s///スキップしました)そして/スラッシュ。これらのファイル名は次のとおりです。

(set -- *; printf '%s\n\n##############\n\n%s\n' "${9}" "${34}")  | cat -A

   ---___ww -_   ---___xx -_   ---___yy -_   ---___zz -_   ---___{{ -_   ---___|| -_   ---$
$
___}} -_   ---___~~ -_   ---___^?^? -_   ---___M-^@M-^@ -_   ---___M-^AM-^A -_   ---___M-^BM-^B -_   ---___M-^CM-^C$
$
##############$
$
 -_   ---___M-ZM-Z -_   ---___M-[M-[ -_   ---___M-\M-\ -_   ---___M-]M-] -_   ---___M-^M-^ -_   ---___M-_M-_ -_$
$
---___M-`M-` -_   ---___M-aM-a -_   ---___M-bM-b -_   ---___M-cM-c -_   ---___M-dM-d -_   ---___M-eM-e -_   ---___$

次に、次のファイルからいくつかのデータをインポートします。

chksqz() ( LC_ALL=C sqz=$1
    set -- * ; set -f ; IFS= ; tc="$*"
    printf '#%s\n' \
        "There are $# files in this test directory." \
        "All filenames combined contain a total of ${#tc} bytes."
    IFS=$sqz ; set -- $* ; IFS= ; sc="$*"  
    printf "%s '$sqz'" \
        "#Of which ${#sc} bytes are not"\
        " and $((${#tc}-${#sc})) bytes are"
    set +f ; unset IFS
    printf ".\n#%s\n#Total:\t%d\n#Other:\t%d\n#'$sqz':\t%d\n" \
        "And to confirm these figures:" \
        $(  printf %s * | wc -c 
            printf %s * | tr -d "$sqz" | wc -c
            printf %s * | tr -dc "$sqz" | wc -c
))
chksqz '_ -'

出力

#There are 101 files in this test directory.
#All filenames combined contain a total of 17744 bytes.
#Of which 2692 bytes are not '_ -' and 15052 bytes are '_ -'.
#And to confirm these figures:
#Total: 17744
#Other: 2692
#'_ -': 15052

さて、今やついにアクションをとる時間です。

ifsqz '_ -'
chksqz '_ -'

出力

#There are 101 files in this test directory.
#All filenames combined contain a total of 2692 bytes.
#Of which 2692 bytes are not '_ -' and 0 bytes are '_ -'.
#And to confirm these figures:
#Total: 2692
#Other: 2692
#'_ -': 0

成功!直接確認できます。

ls

????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
???????????????????????????
???????????????????????????
???????????????????????????
????????????????????????????
????????????????????????????
????????????????
??????????????????????
????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
??????????????????????????
???????????????????????????
???????????????????????????
???????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
????????????????????????????
??????????????????????????
????????????????????????
????????????????????
??????????????????
????????????????????????????
??
????????????????????????????
??????????????????????????
????????????????????????????
????????????????????????????
????????????????????!!""##
??????????????????!!""##$$
????????????????!!""##$$%%
????????????!!""##$$%%&&((
????????!!""??##$$%%&&(())
$$%%&&(())**??++,,..0011
%%&&(())**++??,,..00112233
&&(())**++,,??..0011223344
))**++,,..??0011223344556
**++,,..00??11223344556677
22334455667788??99::;;<<==>>
445566778899??::;;<<==>>??@@
5566778899::;;??<<==>>??@@AA
6778899::;;<<??==>>??@@AABB
8899::;;<<==??>>??@@AABBCCDD
\\]]^^``aa??bbccddeeffgghh
]]^^``aabbc??cddeeffgghhii
^^``aabbccdd??eeffgghhiijj
??@@AABBCCDDEE??FFGGHHIIJJKK
AABBCCDDEEFF??GGHHIIJJKKLLM
BBCCDDEEFFGG??HHIIJJKKLLMMNN
CCDDEEFFGGHHII??JJKKLLMMNNOO
EEFFGGHHIIJJ??KKLLMMNNOOPPQQ
ffgghhiijjkk??llmmnnooppqqrr
gghhiijjkkllmm??nnooppqqrrss
iijjkkllmmnn??ooppqqrrsstt
jjkkllmmnnoo??ppqqrrssttuuvv
kkllmmnnooppqq??rrssttuuvvww
LLMMNNOOPPQQRR??SSTTUUVVWWXX
MNNOOPPQQRRSS??TTUUVVWWXXYY
OOPPQQRRSSTT??UUVVWWXXYYZZ[[
PPQQRRSSTTUUVV??WWXXYYZZ[[\\
RRSSTTUUVVWW??XXYYZZ[[\\]]
ssttuuvvwwxx??yyzz{{||}}~~??
ttuuvvwwxxyyz??z{{||}}~~????
uuvvwwxxyyzz{{??||}}~~??????
wwxxyyzz{{||??}}~~??????????
xxyyzz{{||}}~~??????????????
YYZZ[[\\]]^^??``aabbccddee
ZZ[[\\]]^^``??aabbccddeeff

答え4

次の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' _-'

関連情報