如何根据行首将文件拆分成两部分?

如何根据行首将文件拆分成两部分?

我有这个文件1.txt

-e a
b
-e c

d
-e e
f

我想将其拆分成以下两个文件。

2.txt

-e a
-e c
-e e

3.txt

b
d
f

其中2.txt包含所有以 开头的行-e3.txt包含所有其他行。多余的换行符(例如原始文本中间的额外换行符)可以忽略或保留,顺序无关紧要。

我尝试过使用split,但它看起来不允许我使用模式进行拆分(而是每个拆分文件固定数量的行)。

答案1

使用grep

grep -E '^-e' 1.txt >2.txt
grep -E '[^-]' 1.txt >3.txt

@braemar:使用grep -v相同的正则表达式会错误地检测空行、文本行等。这不是我们想要的。

答案2

这是awk解决方案:

awk '{ if ( /^-/ ) print > "2.txt"; else if ( NF ) print > "3.txt" }' 1.txt

性能测试:

$ cat 1.txt | wc -l | sed -r -e 's/([0-9]{6}$)/ \1/' -e 's/([0-9]{3}$)/ \1 lines/'
1 144 270 lines
$ TIMEFORMAT=%R

$ time awk '{ if ( /^-/ ) print > "2.txt"; else if ( NF ) print > "3.txt" }' 1.txt
0.372

答案3

保留空行:

$ sed -n -e '/^-e/{w 2.txt' -e 'd}' -e 'w 3.txt' 1.txt

给予

$ head {1,2,3}.txt
==> 1.txt <==
-e a
b
-e c

d
-e e
f

==> 2.txt <==
-e a
-e c
-e e

==> 3.txt <==
b

d
f

如果您希望省略空行,请在最后写入时添加“任何字符”正则表达式:

sed -n -e '/^-e/{w 2.txt' -e 'd}' -e '/./w 3.txt' 1.txt

答案4

以下是sed使用delete 标志的解决方案:

sed -e '/^-/!d' -e '/^[[:space:]]*$/d' 1.txt > 2.txt

上述命令有两个正则表达式,第一个'/^-/!d'将匹配所有不以 开头的行-,并且它们将从输出中删除,第二个'/^[[:space:]]*$/d'将匹配所有仅包含空格的行,并且它们将从输出中删除。

sed -e '/^-/d' -e '/^[[:space:]]*$/d' 1.txt > 3.txt

上述命令也有两个正则表达式,第一个'/^-/d'将匹配以 开头的所有行-,并且它们将从输出中删除,第二个与预览情况相同。


另一种方法是保留-n正常输出sed,然后p仅打印匹配的行:

sed -n '/^-/p' 1.txt > 2.txt
sed -n -r '/^(-|[[:space:]]*$)/!p' 1.txt > 3.txt

以下是性能测试:

$ cat 1.txt | wc -l | sed -r -e 's/([0-9]{6}$)/ \1/' -e 's/([0-9]{3}$)/ \1 lines/'
1 144 270 lines
$ TIMEFORMAT=%R

$ time sed -e '/^-/!d' -e '/^[[:space:]]*$/d' 1.txt > 2.txt
0.357
$ time sed -e '/^-/d' -e '/^[[:space:]]*$/d' 1.txt > 3.txt
0.323

$ time sed -n '/^-/p' 1.txt > 2.txt
0.221
$ time sed -n -r '/^(-|[[:space:]]*$)/!p' 1.txt > 3.txt
0.402

相关内容