我有几个文件的格式如下:
...
<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>发布于 2017-03-29 21:40:59
通常,使用正则表达式处理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发布于 2017-04-01 09:38:49
另一种可能的方法是使用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并打印“x”及其值。-t -n --添加一个换行符https://unix.stackexchange.com/questions/354669
复制相似问题