使用awk提取模式之间的文件路径的一部分

时间:2016-10-23 21:21:39

标签: bash awk

我正在尝试从文件路径列表中提取数据,因为我希望创建已完成加载的文件的日志。问题是每个文件路径都不一致,所以我需要在两个正则表达式模式之间寻找部分文件路径。

例如说我想提取两条信息......让我们说/system/.../之间的数据和/data/.../sales/之间的另一条数据

/user/project-x/system/ibm/nyc/data/customers/sales/yyyymmdd
/user/project-x/system/mysql/data/regional/sales/yyyymmdd
/user/project-x/system/mysql/london/data/customers/sales/yyyymmdd
/user/project-x/system/oracle/data/tokyo-customers/Sales/yyyymmdd

因此,当我运行awk脚本时,我将被留下......

ibm      customers
mysql    regional
mysql    customers
oracle   tokyo-customers

无论如何都要进行这种类型的文件路径分割吗?

2 个答案:

答案 0 :(得分:2)

我看到你的路径部分是固定的,所以不需要使用正则表达式。 场分离可以解决问题:

awk -F/ '{print $4,$7}' test.txt

(其中test.txt是您的输入文件)

基本上你告诉awk将斜杠视为字段分隔符,并打印字段#4和#7。

但是用字段查找来回答你的问题呢(虽然更复杂)

awk -F/ '{a="???";b="???";for (i=0;i<NF;i++) {if (tolower($i)=="system") a= $(i+1); if (($i=="data") && (tolower($(i+2))=="sales")) b = $(i+1)}; print a,b}' test.txt

这将像以前一样拆分字段,但会查找上一个/下一个字段值并打印下一个/上一个字段。即使字段不在固定位置也能工作。 如果无法找到模式,则会显示???

我已经包含小写转换,因为Sales出现混合大小写。

答案 1 :(得分:1)

使用sed

sed -E 's_.*/system/([^/]+).*/data/([^/]+)/[Ss]ales/.*_\1 \2_'
  • .*/system/([^/]+).*匹配/system/之后的部分,以及下一个/,并放入捕获的第1组

  • /data/([^/]+)/[Ss]ales/匹配/data//sales/(或/Sales/)之间的部分,并放入第二个捕获的组

  • 在替换中,使用捕获的组,以空格分隔

示例:

$ cat file.txt
/user/project-x/system/ibm/nyc/data/customers/sales/yyyymmdd
/user/project-x/system/mysql/data/regional/sales/yyyymmdd
/user/project-x/system/mysql/london/data/customers/sales/yyyymmdd
/user/project-x/system/oracle/data/tokyo-customers/Sales/yyyymmdd

$ sed -E 's_.*/system/([^/]+).*/data/([^/]+)/[Ss]ales/.*_\1 \2_' file.txt
ibm customers
mysql regional
mysql customers
oracle tokyo-customers