我有一个文件,其中包含约5GB的文本价值。我想打破了这个成多个小文件的基础上,每次一个特定的字符串出现。
我试图做的是把一个脚本,甚至一个一行程序,通过读取文件寻找<ticket>
和</ticket>
,每次它找到它们,它复制这两行加上中间的内容到一个新文件。每次它找到这些字符串的匹配,我需要它创建一个新文件。什么想法会为我做这是这样的:
#!/bin/bash
i=0
for f in BF_File.xml; do
let i++;
sed 's#.*<ticket>\(.*\)</ticket>#\1#' "$f" > Smaller_File_"${i}".xml
done
但这只是将原始文件的内容复制到Smaller_File_1.xml
中
任何帮助将不胜感激!
3条答案
按热度按时间ecfsfe2w1#
假设
<ticket>
和</ticket>
对是 complete 的,这意味着它们都没有丢失,请尝试awk
脚本:或一行代码(可读性较差):
<ticket>
,则设置f
并打开一个新文件。f
,则将该行打印到文件中。</ticket>
,则重置f
并关闭文件。请根据可能的拆分文件数修改位数
%05d
。7cwmlq892#
你的代码是:
for f in BF_File.xml
仅运行一次i
的一次赋值sed
正则表达式贪婪:.*
匹配可能的最长字符串(可以包括...</ticket>...<ticket>...
)sed
在单独的行上运行,因此s
命令将只匹配出现在同一行上的<ticket>
和</ticket>
你说代码“复制这两行代码以及它们之间的内容”,但是你的
sed
命令会丢弃这两行代码。你需要的代码应该是:s#.*\(<ticket>.*</ticket>\)#\1#
(但由于前面的原因仍然会失败)使用
gawk
,您可以指定RS
是正则表达式。假设输入具有以下形式:
然后设置
RS='</?ticket>'
给出记录:a
b
c
d
e
f
g
...从中可以丢弃奇数元素以留下:
b
d
f
...gawk
在读取每条记录时将RT
设置为RS
的实际值,以便可以保存并用于在输出时 Package 记录。i86rm4rw3#
使用
XML
解析器:xmllint
和shell *while循环 *: