linux 如何根据两个字符串之间的内容将文件拆分为多个文件

ekqde3dh  于 2023-04-20  发布在  Linux
关注(0)|答案(3)|浏览(124)

我有一个文件,其中包含约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
任何帮助将不胜感激!

ecfsfe2w

ecfsfe2w1#

假设<ticket></ticket>对是 complete 的,这意味着它们都没有丢失,请尝试awk脚本:

awk '
    /<ticket>/ {f = 1; file = sprintf("Smaller_File_%05d.xml", ++c)}
    f {print > file}
    /<\/ticket>/ {f = 0; close(file)}
' BF_File.xml

或一行代码(可读性较差):

awk '/<ticket>/ {f = 1; file = sprintf("Smaller_File_%05d.xml", ++c)} f {print > file} /<\/ticket>/ {f = 0; close(file)}' BF_File.xml
  • 如果一行匹配<ticket>,则设置f并打开一个新文件。
  • 如果设置了f,则将该行打印到文件中。
  • 如果行匹配</ticket>,则重置f并关闭文件。

请根据可能的拆分文件数修改位数%05d

7cwmlq89

7cwmlq892#

你的代码是:

i=0
for f in BF_File.xml; do
        let i++;
        sed 's#.*<ticket>\(.*\)</ticket>#\1#' "$f" > Smaller_File_"${i}".xml
done
  • for f in BF_File.xml仅运行一次
  • 只会发生对i的一次赋值
  • sed正则表达式贪婪.*匹配可能的最长字符串(可以包括...</ticket>...<ticket>...
  • sed在单独的行上运行,因此s命令将只匹配出现在同一行上的<ticket></ticket>

你说代码“复制这两行代码以及它们之间的内容”,但是你的sed命令会丢弃这两行代码。你需要的代码应该是:s#.*\(<ticket>.*</ticket>\)#\1#(但由于前面的原因仍然会失败)
使用gawk,您可以指定RS是正则表达式。
假设输入具有以下形式:

a<ticket>b</ticket>c<ticket>d</ticket>e<ticket>f</ticket>g...

然后设置RS='</?ticket>'给出记录:abcdefg ...
从中可以丢弃奇数元素以留下:bdf ...
gawk在读取每条记录时将RT设置为RS的实际值,以便可以保存并用于在输出时 Package 记录。

gawk -v RS='</?ticket>' '
    !(NR%2) {
        out = "small" (++n) ".xml"
        print rt $0 RT > out
        close out
    }
    { rt = RT }
' big.xml
i86rm4rw

i86rm4rw3#

使用XML解析器:xmllint和shell *while循环 *:

cat file.xml
<root>
<ticket>foo</ticket>
<ticket>bar</ticket>
<ticket>base</ticket>
</root>
i=1
while IFS= read -r val; do 
    echo "$val" | tee "Smaller_File_$(printf '%.5d' $i).xml"
    ((i++))
done < <(xmllint --xpath '//ticket/text()' file.xml)
foo
bar
base
ls -1 Smaller_File_0*
Smaller_File_00001.xml
Smaller_File_00002.xml
Smaller_File_00003.xml

相关问题