我有一个文件x
,带有分隔符:
The first section
#!
The second section
#!
The third section
我想把它分成一系列单独的文件,例如:
The first section
#!
The second section
#!
The third section
我认为csplit
将成为解决方案,其命令行如下:
$ csplit -sk x '/#!/' {9999}
但是第二个文件(xx01
)最终包含两个分隔符:
#!
The second section
#!
如何以符合POSIX标准的方式完成我想要的任何想法? (是的,我可以找到Perl / Python / Ruby和朋友;但是,重点是扩展我的shell知识。)
我担心我在OSX csplit中发现了一个错误。人们可以给出以下结果,让我知道结果吗?
#!/bin/sh
test -e
work="$(basename $0).$RANDOM"
mkdir $work
csplit -sk -f "$work/" - '/#/' '{9999}' <<EOF
First
#
Second
#
Third
EOF
if [ $(grep -c '#' $work/01) -eq 2 ]; then
echo FAIL Repeat
else
echo PASS Repeat
fi
rm $work/*
csplit -sk -f "$work/" - '/#/' '/#/' <<EOF
First
#
Second
#
Third
EOF
if [ $(grep -c '#' $work/01) -eq 2 ]; then
echo FAIL Exact
else
echo PASS Exact
fi
uname -a
当我在Snow Leopard盒子上运行时,我得到:
$ ./csplit-test
csplit: #: no match
FAIL Repeat
PASS Exact
Darwin lani.bigpond 11.2.0 Darwin Kernel Version 11.2.0: Tue Aug 9 20:54:00 PDT 2011; root:xnu-1699.24.8~1/RELEASE_X86_64 x86_64
在我的Debian框中,我得到了:
$ sh ./csplit-test
csplit: `/#/': match not found on repetition 2
PASS Repeat
PASS Exact
答案 0 :(得分:2)
这似乎在LINUX上对我有用:
csplit -sk filename '/#!/' {*}
,并提供:
$ more xx00
The first section
$ more xx01
#!
The second section
$ more xx02
#!
The third section
您也可以使用Ruby或Perl在一个小小的脚本中执行此操作,并一起摆脱分隔符
在Fedora 13 Linux上:
$ ./test.sh
csplit: `/#/': match not found on repetition 2
PASS Repeat
PASS Exact
Linux localhost.localdomain 2.6.34.8-68.fc13.x86_64 #1 SMP Thu Feb 17 15:03:58 UTC 2011 x86_64 x86_64 x86_64 GNU/Linux
答案 1 :(得分:1)
src ./test_split.sh
csplit: #: no match
FAIL Repeat
PASS Exact
FreeBSD <hostname> 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:55:53 UTC 2010 root@almeida.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC i386
答案 2 :(得分:1)
虽然不理想,但您可以使用awk
执行此类操作。
您的文件:
[jaypal:~/Temp] cat f0
The first section
#!
The second section
#!
The third section
使用此#!
获取所有内容(您可以将其重定向到文件中)
[jaypal:~/Temp] awk '/#!/{exit;}1' f0
The first section
获取#!
后跟内容并在下一个#!
之前拆分。
[jaypal:~/Temp] awk '/^#!/{x++}{print >(x".txt")}' f0
[jaypal:~/Temp] ls *.txt
1.txt 2.txt
[jaypal:~/Temp] cat 1.txt
#!
The second section
[jaypal:~/Temp] cat 2.txt
#!
The third section
使用perl
这样的东西可以轻松解决这个问题 -
#!/usr/bin/perl
undef $/;
$_ = <>;
$n = 0;
for $match (split(/(?=#!)/)) {
open(O, '>temp' . ++$n);
print O $match;
close(O);
}
脚本创建的文件:
[jaypal:~/Temp] cat temp1
The first section
[jaypal:~/Temp] cat temp2
#!
The second section
[jaypal:~/Temp] cat temp3
#!
The third section
答案 3 :(得分:1)
使用 awk 并在linux机器上测试它:
我的 awk 版本:
$ awk --version | head -1
GNU Awk 4.0.0
infile的内容:
$ cat infile
The first section
#!
The second section
#!
The third section
awk 脚本的内容:
$ cat script.awk
BEGIN {
## Set 'Input Record Separator' variable.
RS = "#!";
}
{
## Set an integer variable as output file name.
++filenum;
}
## For first section.
FNR == 1 {
## Remove leading and trailing spaces.
sub( /^\s+/, "", $0);
sub( /\s+$/, "", $0);
## Print to output file.
printf "%s\n", $0 > filenum ".txt"
}
## For sections from second one to last one.
FNR > 1 {
## Remove trailing spaces.
sub( /\s+$/, "", $0);
## Print to output file.
printf "%s%s\n", RS, $0 > filenum ".txt"
}
运行脚本:
$ awk -f script.awk infile
检查输出:
$ ls [0-9].txt
1.txt 2.txt 3.txt
$ cat 1.txt
The first section
$ cat 2.txt
#!
The second section
$ cat 3.txt
#!
The third section