从大型目录中一次高效地连接和删除 1000 个文件

从大型目录中一次高效地连接和删除 1000 个文件

我知道我们可以通过cat file [file] [[file] ...] > joined-file.我有一个目录,其中包含数十万个文件。我想将几组(1000)个文件连接到一个文件中。我有一个非常小的文件集。我想连接 1000 个文件,无论其名称和顺序如何,以便其他服务可以轻松读取并保存内存中的所有文件名以进行操作。

这是我尝试过的

for i in /var/abc/*.csv; do "$i" > file1.csv; rm -rf "$i"; done

但要跟踪另一个变量的计数。有什么有效的方法呢?这样我就不能直接连接1000个文件并移动它们。

为什么是1000?因为该目录包含数十万个文件。我们将每个文件的大小设置为 1-4 KB,只是为了确保一个输出文件的大小不会增长超出限制。我已经按照你的答案尝试过。

cd /var/abc 
for file in $(ls -p | grep -v / | tail -1000); do cat "$file" >>"/var/abcd/xigzag"$tick".csv" && rm -rf "$file"; done

答案1

您不需要循环,您可以告诉cat读取所有文件:

cat /var/abc/*.csv > file1.csv && rm /var/abc/*.csv

只要文件不是太多(但限制很大)。

在两个命令之间使用&&可确保文件仅在成功“复制”时才被删除。

但有一些注意事项:

  • 您不能在与要连接的原始文件相同的文件夹中运行此命令,否则将rm删除聚合,您将丢失所有内容;
  • 如果新的 CSV 文件出现在 的开始cat和 的参数扩展之间rm,它们将被删除而不被复制;
  • 如果任何 CSV 文件在连接后被修改,这些修改将会丢失。

您可以通过在创建输出文件之前存储文件列表来缓解前两个警告:

set -- /var/abc/*.csv
cat -- "$@" > file1.csv && rm -- "$@"

复制文件后,这仍然会丢失对文件所做的任何更改。

要一次连接 1000 个文件(每 1000 个原始 CSV 生成一个 CSV)以及任意数量的文件,您可以在目标目录中按以下步骤操作:

find /var/abc -maxdepth 1 -type f -name \*.csv | split -d -l 1000 - csvlists
for file in csvlists*; do cat $(cat $file) > concat${file##csvlists}.csv && rm $(cat $file); done

/var/abc这将找到named中的所有文件,并在以( , ...)*.csv开头的文件中一次列出1000个文件。然后循环读取每个文件列表,并将列出的 CSV 文件连接到名为 etc. 的文件中以匹配列表。复制每组文件后,原始文件将被删除。csvlistscsvlists00csvlists01forconcat00.csv

此版本假定 CSV 文件的名称不包含空格、换行符等。

答案2

你的命令看起来几乎没问题。只需添加一个catand>>即可实际附加内容:

for i in /var/abc/*.csv; do cat "$i" >> file1.csv && rm -rf "$i";done

我不太明白计数部分。你可以这样做:

let count=0
for i in /var/abc/*.csv; do
  cat "$i" >> file1.csv && rm -rf "$i"
  let count++
done
echo $count files processed.

答案3

zsh

files=(/var/abc/*.csv(N.))
n=0
while (($#files)) {
  cat $files[1,1000] > file$((++n)).csv &&
    rm -f $files[1,1000] || break
  files[1,1000]=()
}

相关内容