1

我有一个包含多个元素的文件<elem>...</elem>。我需要将此文件拆分为每个n包含m元素的文件(传递给我正在使用的 awk 命令的参数)。例如,如果我的原始文件有 40 个元素,我想拆分为 3 个文件(10 个元素、13 个元素和 17 个元素)。

问题是原始文件具有不同结构的元素。

EDITED AFTER fedorqui comment:
I use as awk command as files I want to get at the end of the process. 
That means If I need 3 files with m1, m2 and m3 elements, I will 
execute 3 awk with different parameters

输入示例(file.txt)(5 个元素)

<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>
<elem>ccccc

cccc</elem>

如您所见,第 1/2/4 个元素在一行中,第 3 个元素在 3 行中,没有空行,第 5h 个元素在 3 行中,有一个空行。

元素之间的空行不是问题,但元素内的空行会失败

所需输出的示例:

file_1.txt(2 个元素)

<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>

file_2.txt(2 个元素)

<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>

file_3.txt(1 个元素)

<elem>ccccc

cccc</elem>

AWK 命令

(suffixFile是文件的后缀号。例如fileAux_1.txt、fileAux_2.txt...)

尝试1

awk -v numElems=$1 -v suffixFile=$2 '{
    for(i=1;i<=numElems;i++) {
        printf "<doc>"$i > "fileAux_" suffixFile".txt"
    }
}' RS='' FS='<doc>' file.txt

除元素内的空行外有效。我理解它为什么会失败,因为 RS='' 告诉 awk 用空行分割

尝试 2

awk -v numElems=$1 -v suffixFile=$2 '{
    for(i=1;i<=numElems;i++) {
        printf $i > "fileAux_" suffixFile".txt"
    }
}' RS='<doc>' FS='<doc>' file.txt

另一种方法,但它也失败了

谁能帮我?

提前致谢!

4

1 回答 1

0

假设我正确理解了您的挑战,这是我的尝试:

$ cat script.sh 
#!/bin/bash

awk -v numElems=$1 -v suffixFile=$2 '
        /<elem>/{var++}
        /<\/elem>/{var--; count++} 
        {if(count < numElems || (count == numElems && var == 0)) {
                print $0 >> "file_"suffixFile".txt"
        } else {
                print $0
        } }' $3

该脚本主要使用 来跟踪<elem></elem>闭包,var并使用 来计算对count。然后一个 if 语句决定是否将该行推送到文件中。达到元素总数后,将返回文件的其余部分,以便您可以使用管道重复该过程。

以下是如何使用最终输出运行它的示例:

$ ./script.sh 2 1 file.txt | ./script.sh 2 2 | ./script.sh 1 3
$ tail -n +1 file_*
==> file_1.txt <==
<elem>aaaaaaaa1</elem>
<elem>aaaaaaaa2</elem>

==> file_2.txt <==
<elem>bbbbbbbb
bbbbbbbbb
bbbbbbbbb</elem>
<elem>bbbbbbbb2</elem>

==> file_3.txt <==
<elem>ccccc

cccc</elem>
于 2017-05-31T22:37:01.150 回答