ファイル拡張子を無視し、ディレクトリの内容を名前で繰り返し比較します。

ファイル拡張子を無視し、ディレクトリの内容を名前で繰り返し比較します。

約7,000の音楽ファイルを含むディレクトリがあります。私はLameを使ってその中のすべてのファイルを別々のディレクトリに再帰的に記録し、同じ相対パスとファイル名を持つすべてのファイルを出力しました。出力ファイルの拡張子は.mp3ですが、一部の入力ファイルの拡張子は異なります(.wma、.aacなど)。

出力ディレクトリに約100個のファイルが見つからないファイルの数の違いを見ることができます。私が望むのは、2つのディレクトリを比較してソースにはあるがターゲットにはないファイルのリストを取得することです。ファイル拡張子の違いを無視する必要があることを除いて、これは簡単です。

私はテスト実行をオンにしてrsyncを試しましたが、ファイル拡張子を無視する方法が見つかりませんでした。また、diffを試しましたが、名前で解決し、ファイル拡張子を無視するオプションが見つかりませんでした。私は両方のディレクトリで再帰lsを実行し、ファイル拡張子を削除して出力を比較することができると思い始めましたが、sedまたはawkを使用してls出力を変更することから始める必要があるかもしれません。

ベストアンサー1

リストを表示するには、サブディレクトリで繰り返されるものとそうでないものの2つのバリエーションがあります。すべてbash、ksh、およびzshに関連する構文を使用します。

comm -3 <(cd source && find -type f | sed 's/\.[^.]*$//' | sort) \
        <(cd dest && find -type f | sed 's/\.[^.]*$//' | sort)
comm -3 <(cd source && for x in *; do printf '%s\n' "${x%.*}"; done | sort) \
        <(cd dest && for x in *; do printf '%s\n' "${x%.*}"; done | sort)

zshでは短いです。

comm -3 <(cd source && print -lr **/*(:r)) <(cd dest && print -lr **/*(:r))
comm -3 <(print -lr source/*(:t:r)) <(print -lr dest/*(:t:r))

このコマンドは、2つのファイル()、最初のファイル()のみ、または2番目のファイル()に共通の行を一覧comm表示します。この数字は出力から差し引いた内容を表します。 2つの入力ファイルをソートする必要があります。comm -12comm -23comm -13

ここでファイルは実際にはコマンドの出力です。シェルは<(…)コマンドの引数として「偽」ファイル(FIFOまたは/dev/fd/名前付きファイル記述子)を提供することによってこの構成を評価します。

1 だからここマイナススピーカー完全に理解されます。


ファイルを操作するには、ソースファイルを繰り返す必要があるかもしれません。

cd source
for x in *; do
  set -- "…/dest/${x%.*}".*
  if [ $# -eq 1 ] && ! [ -e "$1" ]; then
    echo "$x has not been converted"
  elif [ $# -gt 1 ]; then
    echo "$x has been converted to more than one output file: " "$@"
  else
    echo "$x has been converted to $1"
  fi
done

おすすめ記事