我有这个文件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
包含所有以 开头的行-e
,3.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
使用d
elete 标志的解决方案:
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