如何匹配具有相同名称的文件并将它们合并到shell脚本中?

时间:2017-02-20 03:46:57

标签: regex bash shell

我正在尝试将几个文件合并到一个具有相似命名模式的文件夹中,而不管该目录。

文件结构如下:

20170219-A20-L1-AB1234_S1_R1_001.txt
20170211-B21-L3-AB1234-2_S1_R1_001.txt
20170210-C20-L1-AB1234-3_S1_R1_001.txt  
20170211-B21-L3-AB1234-2_S2_R1_001.txt
20170210-C20-L1-AB1234-3_S2_R1_001.txt

我的标准是查找包含_S1_S2的文件,并将所有_S1个文件合并到一个新的单个文件中,并将所有_S2个文件合并到一个文件中新的单一文件。

我的预期输出可以是20170219-B21-L3-AB1234-2_S1_R1_001_merge.txt20170219-B21-L3-AB1234-2_S2_R1_001_merge.txt。我对合并文件名没有任何特定要求,但我希望这些合并文件位于同一文件夹中。

我一直在尝试使用grepcut命令,但我的for循环不起作用。我发现很难理解shell中的正则表达式。

请帮我构建逻辑。

3 个答案:

答案 0 :(得分:4)

如果您正在搜索的文件位于工作目录中,但以前的解决方案都不合适,但不会合并其他目录中的任何文件。要重新创建您的问题,我执行了以下操作,然后根据您的初始请求尝试解决该问题:

根据您的规范创建文件:

$ touch $(date +%Y%m%d)_{A,B}{20,21}_L{1,3}_AB1234_{1,3}_S{1,2}_R1_001.txt
$ touch $(date +%Y%m%d)_{A,B}{20,21}_L{1,3}_AB1234_S{1,2}_R1_001.txt
$ ls | wc -l
48

创建了一个参数myText,其中包含48行随机文本生成的Lorem Ipsum:

$ echo "${myText}" | wc -l
    48

myText

为每一行提供一行
$ ls -t1 | awk '{print NR" "$0}' | while read i j; do echo "${myText}" | awk -v var=${i} 'NR==var {print}' >> ${j}; done
$ for i in `ls -t1`; do echo -n " ${i}: "; cat ${i}; done
 20170219_B21_L3_AB1234_3_S1_R1_001.txt: This is additional line two
 20170219_B21_L3_AB1234_3_S2_R1_001.txt: line three
...
 20170219_A20_L3_AB1234_S1_R1_001.txt: Phasellus ut quam eu lacus aliquet vehicula.
 20170219_A20_L1_AB1234_S1_R1_001.txt: Proin nec orci accumsan, pharetra sapien sed, gravida arcu.
 20170219_B21_L3_AB1234_S2_R1_001.txt: Lorem ipsum dolor sit amet, consectetur adipiscing elit

然后我合并了所有... S1 ...和... S2 ...文件(这会发现任何符合我的条件和我的主目录的文件;要追加而不是覆盖,请使用{{ 1}}而不是cat >> file - 取决于在脚本需要重新运行之前是否清理了文件):

cat > file

结果:

$ find ~ -type f -iname "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[A,B]*S1*" -exec cat > AB1234_S1_R1_001_merged.txt {} +
$ find ~ -type f -iname "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_[A,B]*S2*" -exec cat > AB1234_S2_R1_001_merged.txt {} +

这回答了这个问题吗?

答案 1 :(得分:2)

这样的事情:

          $('body').on('submit', '#myform', function (e) {
            e.preventDefault();
            var $form = $(this);        

             $.ajax({
                type: $form.attr('method'),
                url: $form.attr('action'),
                data: $form.serialize(),
                success: function (data) {
                    //action
                },

                error: function(data){
                    $( "#myform input[type='text']" ).next().text( '' );
                    var errors = data.responseJSON;
                    $.each( errors, function( key, value ) {
                      $( "input[name='"+key+"']" ).next().text( value[0] );
                    });
                    }
            });

            return false;
            });

使用#!/bin/bash for i in 'S1' 'S2' do cat *_"$i"_R[0-9]*_[0-9]*.txt > "$i".txt done 语句(本例中为for& S1)中给出的列表,使用正则表达式模式捕获文件,并将输出发送到每个元素的单个文件在列表中。合并的输出文件将为S2S1.txt。如果需要,您可以使用正则表达式使其更严格。

答案 2 :(得分:1)

以下将有所帮助:

cat *_s1*  > 20170219-B21-L3-AB1234-2_S1_R1_001_merge.txt
cat *_s2*  > 20170219-B21-L3-AB1234-2_S2_R1_001_merge.txt