【问题标题】:Bash: split file into multiple files based on certain string and save new filenames into arrayBash:根据特定字符串将文件拆分为多个文件并将新文件名保存到数组中
【发布时间】:2017-07-19 12:11:15
【问题描述】:

我有一个包含以下内容的文件:

(Item)
(Values)
blabla
blabla
(StopValues)
(Item)
(Values)
hello
hello
(StopValues)

我想将其拆分为多个文件,以便一个文件始终包含从(Item)(StopValues) 的内容(包括这两个标签)。此外,由于我必须进一步使用这些文件并使用 mktemp,因此我想在创建每个文件名时将其保存在一个数组中。

为了拆分它们,我使用了 awk 的方法:

  awk '/(StopValues)/{n++}{print >"out" n ".txt" }' mainfile.txt

这里的第一个问题,当提供“一组”数据时,我仍然得到 2 个新的 txt 文件,一个只包含 (StopValues) 标签,另一个只包含这个标签。

第二个问题,我想用mktemp 创建文件,而不是自己命名它们并且我需要它们在一个数组中,如何在 awk 循环中动态创建新文件并将它们的名称保存到数组中?

【问题讨论】:

  • 一个数组,你的意思是 awk 数组还是 bash 数组?
  • 我的意思是一个 bash 数组
  • 您的文件可以有多少个部分/块?
  • 那没有定义,我这样称呼我的脚本cat *.txt | ./script 并且来自 cat 的所有内容都写在一个文件中。当我像这样对所有文件的 cat 进行管道传输时,是否有可能查看哪些内容来自哪个“cat(ed)文件”,分别将其拆分并直接将其作为数组获取?因为如果可能的话,我所做的一切都不再需要了
  • 好的,一切都清楚了,发布我的答案。

标签: arrays string bash file


【解决方案1】:

@试试:

awk '/(Item)/{A=1;count++} A{VAL=VAL?VAL ORS $0:$0} /(StopValues)/{A="";print VAL > "out" count ".txt";VAL=""}'   Input_file

将创建 2 个文件 out2.txt 和 out1.txt。

编辑:现在也添加非单线形式的解决方案。

awk '/(Item)/{
                A=1;
                count++
             }
    A        {
                VAL=VAL?VAL ORS $0:$0
             }
    /(StopValues)/{
                        A="";
                        print VAL > "out" count ".txt";
                        VAL=""
                  }
    '    Input_file

【讨论】:

    【解决方案2】:

    首先是命令:

    arr=($(awk 'BEGIN{cmd="mktemp -u"; cmd|getline tmp}
    {print > tmp}/\(StopValues/{a[++i]=tmp;close(cmd);close(tmp); cmd|getline tmp;}END{for(i=1;i<=length(a);i++)print a[i]; }' inputFile ))
    

    awk 部分:

    awk 'BEGIN{cmd="mktemp -u"; cmd|getline tmp}
         {print > tmp}
         /\(StopValues/{a[++i]=tmp
                        close(cmd)
                        close(tmp)
                        cmd|getline tmp} 
        END{for(i=1;i<=length(a);i++)print a[i]; }' inputFile
    

    有了这个inputFile (f):(我添加了第三块)

    kent$  cat f
    (Item)
    (Values)
    blabla
    blabla
    (StopValues)
    (Item)
    (Values)
    hello
    hello
    (StopValues)
    (Item)
    (Values)
    hello
    hello
    (StopValues)
    

    awk 会输出:

    #The filenames can be different.
    /tmp/tmp.DRaLMsXROR
    /tmp/tmp.yUL6GO4xtv
    /tmp/tmp.Kb0UxsHVno
    

    所以你可以看到输出有 3 个临时文件。每个文件都包含一个输入文件块。

    输出具有临时文件名,我们将其放在 bash 数组声明中,因此我们将它们放在数组中。所以放在一起,我们做一个测试:(这里我只是检查第一个块/临时文件):

    kent$  arr=($(awk 'BEGIN{cmd="mktemp -u"; cmd|getline tmp}                                                                                                                  
        {print > tmp}/\(StopValues/{a[++i]=tmp;close(cmd);close(tmp); cmd|getline tmp;}END{for(i=1;i<=length(a);i++)print a[i]; }' f ))
    
    kent$  echo ${arr[*]}                                                                                                                                                       
    /tmp/tmp.fcf7ac0eVl /tmp/tmp.Rjru5psFQB /tmp/tmp.ldaBWCucNg
    
    kent$  echo ${arr[1]}
    /tmp/tmp.fcf7ac0eVl
    
    kent$  cat $(echo ${arr[1]})                              
    (Item)
    (Values)
    blabla
    blabla
    (StopValues)
    

    【讨论】:

      猜你喜欢
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2015-08-01
      相关资源
      最近更新 更多