曲ファイルリストのパターンマッチングとテキスト処理

曲ファイルリストのパターンマッチングとテキスト処理

file22つのファイルがありますが、存在しないファイルを含む新しいファイルを作成しようとしていますfile1。ソースファイルはソートされません。

今、トリッキーな部分があります。ファイルの一部の行は次の形式に従います。

./$ARTIST/$ALBUM/$N1 - $N2 - $TITLE.(flac|mp3)
./$ARTIST/$ALBUM/$N1 - $TITLE.(flac|mp3)
./$ARTIST/$ALBUM/$N1. $TITLE.(flac|mp3)

$N1ここで、合計$N2は1〜3桁の数字です(例01、、、、12132

$ARTIST、および-を含む任意の英数字で構成できますが、/は含まれません$ALBUM$TITLE

flacmp3orで終わる行が一致すると見なされ、その行を$ARTIST除外したいと思います。$ALBUM$TITLE

はいfile1

./The BEATLES/white album/01. Revo-lution.flac
./123-123/234-234/01 - 02 - 3769.flac
./THE BEATLES/abbey road/cover.jpg

はいfile2

./The BEATLES/white album/01. Notinfile1.flac
./123-123/234-234/03. 3769.flac
./THE BEATLES/abbey road/cover.jpg

結果ファイル

./The BEATLES/white album/01. Notinfile1.flac

編集する:

私はこの問題について考えて解決策を見つけましたが、コーディングを助ける人が必要です。

両方のファイルの各行に対して、次の方法を使用してキーを生成できます。ファイル間のキーの後続の比較は、file2キーがファイルのキーと一致しない行を出力するために使用できます。file1

キーは次のように生成されます。

flac行がまたはで終わらない場合、mp3キーは行自体です。

それ以外の場合は、最初の発生または.最後-の発生を確認してください/

この場合、キーは.ポイントの後ろにコンテンツが$ARTIST/$ALBUM/$TITLEある場所です。$TITLE

この-場合、最後の行の後の行の部分のダッシュ数を数えます/

$ARTIST/$ALBUM/$TITLE見つかった場合は、ダッシュの後ろにコンテンツがある場所がキーです。$TITLE

複数のダッシュが見つかった場合は、最初のダッシュと2番目のダッシュの間の内容が純粋に数字と空白であることを確認してください。もしそうなら、$TITLE2回目のダッシュ以降です。そうでない場合は、$TITLE最初のダッシュ以降。

誰かが私がコーディングするのを助けることができますか?

答え1

ファイルをソートされた順序でソートすると、ファイルを比較するのに役立つことがよくあります。重複エントリを削除して、-u出力の各行を一意にします。

sort -u file1 > file1.sorted
sort -u file2 > file2.sorted

commソートされたファイルを比較できますが、リテラルテキストのみ可能です。したがって、問題は減りますが、正確に一致するものだけがフィルタリングされます。-1最初のファイルに固有の行を削除し、-32つのファイルパラメータに共通の行を削除します。これにより、2番目のファイルに一意の行が残ります。

comm -1 -3 file1.sorted file2.sorted > file2.reduced

今、私たちはこの(希望的に)小さいファイルに対して複雑な作業をするだけです。

sed 's#^\./##' file2.reduced | while read line; do
  artist_album=${line%/*}
  filename=${line##*/}
  title=$(echo "$filename" | sed 's/^[0-9]\{1,3\}\. //;t;s/^[0-9]\{1,3\} - [0-9]\{1,3\} - //;t;s/^[0-9]\{1,3\} - //')
  extension=${title##*.}
  title=${title%.$extension}
  # We use fixed strings in case there are special chars in the file name
  # If the file names are "regex-save" we can use one grep instead:
  # ! grep -q -E "^\./$artist_album/.*$title\.(mp3|flac)\$" file1.sorted
  if ! grep -F "./$artist_album/" file1.sorted | grep -F -e "$title." | grep -q -E '(mp3|flac)$'; then
    echo "./$line"
  fi
done > results

関連情報