【问题标题】:concatenating batch of files in a folder连接文件夹中的一批文件
【发布时间】:2015-12-14 19:37:39
【问题描述】:

我正在使用 Ubuntu 操作系统。我有一个文件夹,其中的文件名为:

part-r-00000_dep1.csv
part-r-00000_dep1.csv
part-r-00000_dep1.csv
.
.
.
part-r-000799_dep1.csv

我需要将每20个文件连接成一个新文件,所以我使用了以下命令:

cat part-r-0000*_dep1.csv part-r-0001*_dep1.csv > part_0-19.csv
cat part-r-0002*_dep1.csv part-r-0003*_dep1.csv > part_20-39.csv
cat part-r-0004*_dep1.csv part-r-0005*_dep1.csv > part_40-59.csv
cat part-r-0006*_dep1.csv part-r-0007*_dep1.csv > part_60-79.csv
.
.

但是,我需要多次运行此命令到文件夹末尾。有没有办法让它更聪明、更高效?我对这个操作系统没有太多经验,所以我很乐意在这方面得到一些帮助。

【问题讨论】:

    标签: linux bash concatenation batch-processing cat


    【解决方案1】:

    你可以这样写:

    for (( i = 0 ; i < 800 ; i += 20 )) ; do
        for (( j = i ; j < i + 20 ; ++j )) ; do
            cat "part-r-$(printf %05d "$j")_dep1.csv"
        done > "part_$i-$((i+19)).csv"
    done
    

    这里i 取值 {0, 20, 40, ..., 780}(这样你就可以写信给part_0-19.csvpart_20-39.csv,等等),如果(例如)i20,然后 j 取值 {20, 21, ... 39}(这样您就可以从 part-r-00020_dep1.csv, part-r-00021_dep1.csv 等中读取)。

    (免责声明:未经测试。)

    【讨论】:

    • 感谢您的回答。我尝试使用您的代码并得到:Syntax error: Bad for loop variable。知道为什么吗?
    • @Supertwister:啊,是的。您的问题被标记为 [bash],但您可能是从 Ubuntu 交互式 shell 运行它,默认情况下它实际上是 Dash。 (Dash 没有 Bash 的所有功能;相反,它针对速度和简单性进行了优化。)最简单的解决方法是打开 bash,然后运行我提供的命令。
    • 谢谢。效果很好:)
    【解决方案2】:

    您可以将所有输入文件存储在一个数组中,然后使用数组上的子字符串扩展运算符将名称以块的形式传递给cat

    batch_size=20
    
    files=(part-r-*_dep1.csv)
    
    for ((start=0; start < ${#files[@]}; start+=batch_size)); do
        cat "${files[@]:start:batch_size}" > part_${start}_$((start+batch_size-1)).csv
    done
    

    (这与 ruakh 的答案基本相同,但它们的数组可让您最大限度地减少调用 cat 的次数。)

    【讨论】:

    • 感谢您的回答。我刚刚测试了你的脚本,得到了Syntax error: "(" unexpected。知道为什么吗?
    • +1。恕我直言,这种方法与我的方法之间的主要区别在于,这种方法是由文件名实际驱动的,而我的驱动是由它们所期望的驱动。如果缺少一些数字,那么这两种方法都会失败,但方式不同。 :-P 它们都是工具包中的有用方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-24
    • 1970-01-01
    • 2014-04-03
    相关资源
    最近更新 更多