ファイル拡張子に基づいてファイルを並べ替える

ファイル拡張子に基づいてファイルを並べ替える

拡張子に従ってファイルをソートし、正しいフォルダに配置するスクリプトを作成しました。たとえば、abc.jpgディレクトリに配置されますjpg

#!/bin/bash
#this script sorts files according to their extensions
oldIFS=$IFS
IFS=$'\n'
(find . -type f) > /tmp/temp
for var in `cat /tmp/temp`
do
name=`basename "$var"`
ext=`echo $name | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2- | cut -d'.' -f2-`
mkdir -p $ext
mv "$var" $ext/ 2> /dev/null
done
IFS=$oldIFS

このスクリプトの問題:

  1. IFSの使用に関しては、IFSの使用を避けるように努力する必要があります。
  2. ファイル拡張子のないファイルはソートされません。
  3. bzというフォルダにabc.tar.bzなどのファイルを並べ替えますが、これらのファイルはtar.bzフォルダに配置する必要があります。
  4. ファイルに多くの数値が含まれている場合は、私のスクリプトの9行をご覧ください。何もないよりも(その名前に)ポイントを与えます。cut -d'.' -f2-スクリプトでは、ファイル名が拡張部分に含まれます。
    たとえば、名前付きファイルはi.am.live.in.india.and.i.study.computer.science.txt名前付きフォルダに配置されます。study.computer.science.txt

また、このスクリプトを小さく、きれいにするために調整を提案することもできます。

ベストアンサー1

サブディレクトリに再帰

解析された出力はfind信頼できません。ファイル名に改行があるとどうなりますか?find … -exec …安定した処理を保証するために使用されます。

find . -type f -exec sh -c '…' {} \;

シェルの部分はを受け取ります$0。これは別のシェルプロセスであり、親スクリプトから変数や関数を継承しません。同じシェルサブプロセスを使用して複数のファイルを処理すると、処理速度が向上します。

find . -type f -exec sh -c 'for x; do … done' _ {} +

今回は、ループ内でファイル名が変数にありますx

ファイル名の分解

外部ユーティリティ(例:など)を呼び出すことはsed脆弱cutです。特定のファイル名が破損しないように注意してください。これは必要ありません。シェルの組み込み文字列処理機能だけで必要な操作を実行できます。ファイル名が与えられた場合$x:

directory=${x%/*}
basename=${x##*/}
extension=…
if [ -n "$extension" ]; then
  mkdir -p "$directory/extension"
  mv "$x" "$directory/extension"
fi

拡大する

ファイル拡張子とは何ですか?.名前の1つの後の部分です。どちらにも標準はありません。または同じ場合は、foo.tar.gz拡張子が何であるかを決定しますbar-1.2

foo-1.2.tar.gz以下は、一般的な圧縮拡張がネストされていると見なされ、拡張があると見なされるように拡張に文字を含める必要があるいくつかのサンプルコードですtar.gz

extension=
while case "${basename##*.}" in
        gz|bz2|xz) extension=.${basename##*.}$extension;; # stackable extension
        *) false;;
do
  basename=${basename%.*}
done
case "${basename##*.}" in
  "$basename") :;; # no . ==> no extension
  *[!0-9A-Za-z]*) :;; # only allow alphanumeric characters
  *[A-Za-z]*) extension=${basename##*.}$extension;; # non-stackable extension
  *) false;; # require at least one letter
esac
extension=${extension#.}

おすすめ記事