我有几个格式如下的文件:
...
<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