文本处理:提取文件的一部分并将它们写入一行

文本处理:提取文件的一部分并将它们写入一行

我有几个格式如下的文件:

...
<title> Field1 : DATA_FIELD_1</title>
...
<i class="blablabla"></i> <b>Field2 : </b> <span>DATA_FIELD_2</span>
...
<i class="blablabla"></i> <b>Field3 : </b> <span>DATA_FIELD_3</span>
...
<i class="blablabla"></i> <b>Field4 : </b> <span>DATA_FIELD_4</span >
...
<i class="blablabla"></i> <b>Field5 : </b> <span>DATA_FIELD_5 </span>
...

我想读取每个文件,获取每个字段的数据,然后以管道分隔的格式将其写入新文件。

例如:

FileID | Field1 | Field2 | Field3 | Field4 | Field5
1 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
2 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
3 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5
4 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5

我设法使用以下命令通过 grep 错误地提取数据:

grep -o 'Field1 : .*\|Field2 : .*\|Field3 : .*\|Field4 : .*\|Field5 : .*' File-* >> NewFile

但这是我得到的结果

File-1:Field1 : DATA_FIELD_1</title>
File-1:Field2 : </b> <span>DATA_FIELD_2</span>
File-1:Field3 : </b> <span>DATA_FIELD_3</span>
File-1:Field4 : </b> <span>DATA_FIELD_4</span >
File-1:Field5 : </b> <span>DATA_FIELD_5 </span>
File-2:Field1 : DATA_FIELD_1</title>
File-2:Field2 : </b> <span>DATA_FIELD_2</span>
File-2:Field3 : </b> <span>DATA_FIELD_3</span>
File-2:Field4 : </b> <span>DATA_FIELD_4</span >
File-2:Field5 : </b> <span>DATA_FIELD_5 </span>
File-3:Field1 : DATA_FIELD_1</title>
File-3:Field2 : </b> <span>DATA_FIELD_2</span>
File-3:Field3 : </b> <span>DATA_FIELD_3</span>
File-3:Field4 : </b> <span>DATA_FIELD_4</span >
File-3:Field5 : </b> <span>DATA_FIELD_5 </span>

答案1

另一种可能的方法是使用 XML 处理器。在本例中为 XMLstarlet。

xmlstarlet sel -t -v 'substring-after(//title,":")' \
                  -m //span -o "|" -v .  \
               -t -n  *.xml

在哪里:

  • sel -t-- 根据以下模板选择XML部分
  • -v 'substring-after(//title,":")'-- 是“:”之后的标题值
  • -m //span -o "|" -v . -- 匹配span并打印“|”及其价值
  • -t -n-- 添加换行符

答案2

一般来说,使用正则表达式处理 HTML/XML 不是一个好主意,因为它们的表达能力不足以处理所有极端情况。但是,您的 grep 输出表明我们可以根据您的具体情况进行。

以下是使用 sed 处理 grep 命令输出的方法:

sed -e 'N;N;N;N;s/^File-\(.*\):Field1 : \(.*\)<\/title>.*Field2 : .*<span>\(.*\)<\/span *>.*Field3 : .*<span>\(.*\)<\/span *>.*Field4 : .*<span>\(.*\)<\/span *>.*Field5 : .*<span>\(.*\)\s*<\/span *>/\1 | \2 | \3 | \4 | \5 | \6/'

说明:

  • N;N;N;N;:这用于连接第五行到第五行(以便将文件中的所有字段放在同一行中)
  • s/:这将启动替换命令,第一部分是匹配,第二部分是替换
  • ^File-\(.*\)::这与文件号匹配
  • Field1 : \(.*\)<\/title>:这与第一个字段匹配
  • .*Field2 : .*<span>\(.*\)<\/span *>: 这与第二个匹配
  • ...
  • /\1 | \2 | \3 / \4 | \5 | \6/:这是替换部分:\(.*\)第一部分中由 分隔的每个组都被捕获并可通过特殊变量\1\2等重用。

结果:

1 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5 
2 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5 
3 | DATA_FIELD_1 | DATA_FIELD_2 | DATA_FIELD_3 | DATA_FIELD_4 | DATA_FIELD_5

相关内容