bashスクリプト:これらのタスクを実行するよりエレガントな方法:

bashスクリプト:これらのタスクを実行するよりエレガントな方法:

次の3つのファイルがあります。

File.txt.7z=5.4GB
ファイル 1.txt.7z=251M
ファイル 2.txt.7z=7.7M

ディレクトリ内の唯一のファイルは次のとおりです。

$ tree
.
├── file.txt.7z
├── file-1.txt.7z
└── file-2.txt.7z

欲しい

  • ファイルの解凍
  • 1つのファイルにマージ
  • マージされたファイルを500,000のラインファイルに分割
  • 結果は ".txt"拡張子を持つ多くのファイルです。

次に、次のように実装します。

p7zip -d "*.txt.7z"
cat file-1.txt >> file.txt
rm file-1.txt
cat file-2.txt >> file.txt
rm file-2.txt
split -l 500000 file.txt
for f in *; do mv "$f" "$f.txt"; done

どうすれば、よりエレガントな方法でこれを達成できますか?

答え1

7za+splitソリューション(シングルパイプライン):

7za e "*.7z" -so 2> /dev/null | split -l500000 --additional-suffix=".txt" --numeric-suffixes=1 - "file"

-7zaオプション:

  • e- アーカイブ抽出/圧縮解除

  • -so- STDOUTにコンテンツを書き込む


-splitオプション:

  • --additional-suffix=".txt".txt- 生成されたすべてのファイル名にサフィックスを追加します。

  • --numeric-suffixes=1- 次に始まる数字の接尾辞を使用してください。1

  • -(ハイフン) - STDIN(標準入力)からデータを読み込みます。

  • "file"- すべての結果ファイル名の共通プレフィックス


上記のコマンドは、次file01.txtの命名形式でファイルを生成しますfile02.txt

答え2

--filter配管と開梱オプションが利用可能ですsplit

p7zip -d *.txt.7z
cat file.txt file-1.txt file-2.txt | split -l 500000 --filter='> $FILE.txt'
rm file*

次の文書は次のとおりです--filter option

‘--filter=COMMAND’
     With this option, rather than simply writing to each output file,
     write through a pipe to the specified shell COMMAND for each output
     file.  COMMAND should use the $FILE environment variable, which is
     set to a different output file name for each invocation of the
     command.  For example, imagine that you have a 1TiB compressed file
     that, if uncompressed, would be too large to reside on disk, yet
     you must split it into individually-compressed pieces of a more
     manageable size.  To do that, you might run this command:

          xz -dc BIG.xz | split -b200G --filter='xz > $FILE.xz' - big-

     Assuming a 10:1 compression ratio, that would create about fifty
     20GiB files with names ‘big-aa.xz’, ‘big-ab.xz’, ‘big-ac.xz’, etc.

teeすべての出力を含むファイルを保持する必要がある場合は、標準入力を標準出力にコピーし、引数として指定されたファイルをコピーすることができます。

cat file.txt file-1.txt file-2.txt |
    tee all.txt |
    split -l 50000 --filter='> $FILE.txt'

関連情報