Regex 将文件分为多个文件

Regex 将文件分为多个文件,regex,bash,Regex,Bash,我有一个大文件,格式如下: From fc2868d745defcc4deb0ebdce8fe8dac78b447ea Mon Sep 17 00:00:00 2001 From: email address message content From 39a833c2f01030619629daa3b613e3985b2e4e7a Mon Sep 17 00:00:01 2001 From: email address message content From 833c2f01030

我有一个大文件,格式如下:

From fc2868d745defcc4deb0ebdce8fe8dac78b447ea Mon Sep 17 00:00:00 2001
From: email address
message content

From 39a833c2f01030619629daa3b613e3985b2e4e7a Mon Sep 17 00:00:01 2001    
From: email address
message content

From 833c2f01030619629daa3b613e3985b2e4e7a427 Mon Sep 17 00:00:01 2001
From: email address
message content
我想将文件拆分为多个文件,因此第一个文件包含

    From fc2868d745defcc4deb0ebdce8fe8dac78b447ea Mon Sep 17 00:00:00 2001
    From: email address
    message content
下一个文件包含下一节

确定下一个文件的键是“From[a-z][0-9]”

所以“从空间中找到一些字母/数字”

消息内容为多行,最多1000行

有没有办法在bash中实现这一点


包含3条消息的示例:

也许您可以使用此regexp

(From\s.*\n+From:\s+.*\n+.*\n)
请参见此示例:

您可以使用此awk:

awk '/^From [[:alnum:]]+/{if (fn) close (fn); fn = "file" ++i ".txt"}
          {print > fn} END{close(fn)}' file

这将创建输出文件,如
file1.txt
file2.txt
file3.txt
,以下模式将起作用:

(^From.*\n)(From:.*\n)((?!From)[\s\S])*$
  • 第1组:匹配从到当前行末尾的所有内容
  • 第2组:匹配从:到当前行末尾的所有内容
  • 第3组:匹配所有内容,包括换行符,除了来自的

Aaaghh…原来这个大文件来自git,可以使用git-mailsplit进行拆分(
git-mailsplit
:)

git邮件拆分 将mbox文件或Maildir拆分为文件列表:“0001”“0002”。。在指定的目录中,以便您可以从那里进一步处理它们

#脚本20151110f.sh
#输入文件:20151110f.dat
#用法bash 20151110f.sh 20151110f.dat
inf=$1#源文件
num=1
而read-r行
做
回显[a-z0-9]中的“$line”| grep-q”#检查是否有新消息
如果[$?-等式0]
然后
file=“file”${num}.dat
回显“$line”>$file
num=$((num+1))#inc,以便下一个文件名将高一个
其他的
回显“$line”>>$file
fi
完成<“$inf”

消息可以多行显示还是只显示一行?我已经更新了问题。消息将跨越多行。10到1000之间的任意值。如图所示,在每个
from…
行之前是否有一个空行?是。将有一个空行。如果邮件内容为多行,则似乎不起作用。您可以将所有数据粘贴到pastebin中吗?(删除所有私有数据)-但这对于获取数据的结构非常重要。我已将pastebin添加到OP中。如果[[$line==”来自“[a-z0-9]*]”,则可以删除grep:
的使用;然后
另外,要保留前导/尾随空格,请使用
而IFS=read-r line
消息内容中会有空行,因此您只想从
记录中增加
的文件名,但将每条记录打印到“当前”文件名。这并不能回答问题。若要评论或要求作者澄清,请在其帖子下方留下评论。-@不,这是一个答案。@KevinGuan,对于这个问题的答案,我期待的不仅仅是“使用这个工具”…@aschipfl这是个好主意。所以要说:虽然这个工具可以解决这个问题,但它确实有助于提高你文章的质量。请记住,您将在将来回答读者的问题,而这些人可能不知道您的工具建议的原因。
#script 20151110f.sh  
#input file: 20151110f.dat  
#usage bash 20151110f.sh 20151110f.dat  

inf=$1 # source file  
num=1
while read -r line  
do
    echo "$line" | grep -q "From [a-z0-9]" # check if a new message  
    if [ $? -eq 0 ]
    then
        file="file"${num}.dat
        echo "$line" > $file
        num=$((num + 1))  #inc so that next file name will be one higher  
    else
        echo "$line" >> $file
    fi
done < "$inf"