名前は同じですが、拡張子が別のファイルを圧縮する方法は?

名前は同じですが、拡張子が別のファイルを圧縮する方法は?

次のファイルを含む大きなディレクトリがあります。

file1.txt
file1.meta
file1.csv
file2.txt
file2.meta
file2.csv
file2.abc

次のようなzipファイルを作成したいと思います。

file1.zip
file2.zip

頑張りました

ls -1 ~/TEMP | sed 's/\.[a-z]*//g' | uniq | awk '{print $NF}' | xargs -i zip {}.zip ~/TEMP/{}.*

ただし、これはファイルに資金を調達できないというエラーメッセージのみを表示します。問題はワイルドカード*にあるようです。

zip error: Nothing to do! (file1.zip)
    zip warning: name not matched: /home/user/TEMP/file.*

答え1

噴射するジェフの考えしかし、リストを使用せずに:

for fname in *.*; do
    prefix=${fname%.*}
    [ ! -f "$fname" ] || [ -f "$prefix.zip" ] && continue
    zip "$prefix" "$prefix".*
done

このループは、現在のディレクトリ内の1つ以上のドット文字を含むすべての名前を繰り返します。

ループの本文は、現在のファイル名の最後の点の後のビットを削除してファイル名のプレフィックスを抽出します(fromの代わりにinを%%使用)。%最初指す)。次に、名前が実際に一般的なファイル名(またはファイルへのシンボリックリンク)かどうか、およびそのファイルに対応するZipアーカイブがすでに存在するかどうかをテストします。

ファイルが通常のファイル(またはシンボリックリンク)であり、アーカイブが存在しない場合は、zipこのファイルを呼び出してアーカイブを作成します。

答え2

1つの方法はbashで(表示後):

  1. ファイル名プレフィックスのリストを連想配列として収集します。

    declare -A prefixes
    for f in *; do prefixes[${f%%.*}]=1; done
    
  2. プレフィックスを繰り返してzipファイルを作成します。

    for p in "${!prefixes[@]}"; do zip "$p" "$p".*; done
    

関連情報