首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >文本处理:提取文件的部分并将其写入一行。

文本处理:提取文件的部分并将其写入一行。
EN

Unix & Linux用户
提问于 2017-03-29 20:42:31
回答 2查看 298关注 0票数 1

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

代码语言:javascript
复制
...
<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>
...

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

例如:

代码语言:javascript
复制
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命令以不适当的方式提取数据:

代码语言:javascript
复制
grep -o 'Field1 : .*\|Field2 : .*\|Field3 : .*\|Field4 : .*\|Field5 : .*' File-* >> NewFile

但这是我得到的结果

代码语言:javascript
复制
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>
EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2017-03-29 21:40:59

通常,使用正则表达式处理HTML/XML是个坏主意,因为它们的表达能力不足以处理所有的角落情况。然而,您的grep输出表明,我们可以在您的确切情况下。

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

代码语言:javascript
复制
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等被捕获和重用。

结果:

代码语言:javascript
复制
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
票数 0
EN

Unix & Linux用户

发布于 2017-04-01 09:38:49

另一种可能的方法是使用XML处理器。在这种情况下,XMLstarlet。

代码语言:javascript
复制
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 --添加一个换行符
票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/354669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档