30000個のtxtファイルを含むフォルダがあり、各ファイルのサイズは50-60kbです。 2.5mb txt ファイルにマージする必要があります。そして、マージ中のファイルを削除してください。私のコードは次のようになります。for f in *,50; do cat file1,file2...file49 > somefile.txt;done
もちろんこれは擬似コードです。ファイルを50の束にマージしてから、使用したファイルを削除する必要があります。誰でも私を助けることができますか?
ベストアンサー1
そしてzsh
:
files=( ./input-file*(Nn.) )
typeset -Z3 n=1
while
(( $#files > 0 )) &&
cat $files[1,50] > merged-file$n.txt &&
rm -f $files[1,50]
do
files[1,50]=()
((n++))
done
./input-file*(Nn.)
一致するファイルに展開されますが、./input-file*
3つのグローバル修飾子を使用してさらに分類されます。
N
:nullglob: 一致するものが存在しない場合、エラーによって中断されるのではなく、glob 拡張を null にします。 globで配列を設定するときにこれが必要であり、配列が空であっても大丈夫です。n
::numericglobsort
デフォルトの語彙ソートを数値ソート(実際には2つの組み合わせ)に変更します。言い換えれば、input-file2
フロントソートです。input-file10
.
: 限定定期的なファイル(ディレクトリ、シンボリックリンク、FIFOを無視...)
typeset -Z3 n
$n
幅が3になるまで変数を0で埋めて、次のようにしますmerged-file001.txt
。 ... merged-file049.txt
...
次に、配列に要素があり、エラーがない限り、$files
一度に50のバッチ(および最後のバッチで残っているすべての要素)を連結して繰り返します。
bash 4.4+およびGNUツールにも同じことが当てはまります。
readarray -td '' files < <(
LC_ALL=C find . -maxdepth 1 -name 'input-file*' -type f -print0 |
sort -zV
)
n=0
set -- "${files[@]}"
while
(( $# > 0 )) &&
printf -v padded_n %03d "$n" &&
cat "${@:0:50}" > "merged-file$padded_n.txt" &&
rm -f "${@:0:50}"
do
shift "$(( $# >= 50 ? 50 : $# ))"
((n++))
done
find
zshが機能している場合、./input-file*(N.)
数値sort -V
(バージョン)ソートは位置引数を使用し、配列は非常に制限されているため、shift
ループ内で配列を使用します。bash