首页 > 解决方案 > 使用 Unix/Linux 命令遍历一定数量的行后,根据模式拆分一行

问题描述

我有一个 100469448 行数的文件。我想以这样的方式将文件分成两部分,即在解析了几乎一半的行数后,它会查找“ </ abc> 和一个空行”并从下一行拆分。

示例文件

<abc>
d
f
.
.
.
</abc>
x
d
w            (line number 50469450)
</abc>

<abc>
w
d
s
etc

上面的文件应该被拆分成两个文件,文件1(遍历几乎一半的文件后拆分)

<abc>
d
f
.
.
.
</abc>
x
d
w                          (line number 50469450)
</abc>

和文件2

<abc>
w
d
s
etc

标签: linuxshellunixamazon-ec2command-line

解决方案


split您可以使用和分两步完成csplit

假设您的输入文件如下所示:

$ cat infile
<abc>
a
b
c
</abc>

<abc>
d
e
f
g
h
i
j
k
l
m
</abc>

<abc>
n
o
</abc>

<abc>
p
q
r
</abc>

首先,我们拆分成两个文件:

split -l $(($(wc -l < infile) / 2 + 1)) infile

split -l n分割成文件,n每个文件都有行。我们想得到两个文件,所以我们取输入行数并将其分成两半:$(wc -l < infile) / 2. 这是整数除法,所以对于奇数行(比如 11 行),我们最终会得到三个文件(5、5 和 1 行);为了避免这种情况,我们加 1。

我们现在有这两个文件:

xaa

<abc>
a
b
c
</abc>

<abc>
d
e
f
g
h
i
j
k

xab

l
m
</abc>

<abc>
n
o
</abc>

<abc>
p
q
r
</abc>

我们希望第一部分xab成为第一个文件的一部分。为此,我们使用csplit分割模式:

csplit xab '/<abc>/'

这分为xab两个新文件:

xx00

l
m
</abc>

xx01

<abc>
n
o
</abc>

<abc>
p
q
r
</abc>

我们想要的两个文件是xaaplusxx00xx01. 我们连接并重命名:

cat xaa xx00 > file1
mv xx01 file2

并清理:

rm xaa xab xx00

评论

GNUsplit有一个选项来规定要拆分的文件数量:

split -n2 infile

或者,为了防止分割线:

split -n l/2 infile

但输出文件可能有不同数量的行,因为拆分是按字节大小而不是行数。


推荐阅读