首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在linux中使用awk或sed解析简单字符串

在linux中使用awk或sed解析简单字符串
EN

Stack Overflow用户
提问于 2021-11-17 10:17:45
回答 8查看 352关注 0票数 4

原始字符串:

A/trunk/apple/B/trunk/apple/Z/trunk/orange/citrus/Q/trunk/melon/juice/venti/straw/

目录的深度将有所不同,但/trunk部件将始终保持不变。/trunk前面的一个字符就是这条线的指示器。

期望产出:

代码语言:javascript
运行
复制
A /trunk/apple
B /trunk/apple
Z /trunk/orange
Q /trunk/melon/juice/venti/straw

*编辑

对不起,我犯了一个错误,在原始字符串中的每个路径的末尾添加了一个斜杠,这使输出变得很混乱。原来的字符串在大写字母前面没有斜杠,但我会留着它。

我的尝试:

echo $str1 | sed 's/\(.\/trunk\)/\n\1/g'

我觉得它应该有效,但它不起作用。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2021-11-17 10:21:21

为了处理复杂的样本输入,例如在哪可以有N个/数和中继线后的值,请尝试如下。

代码语言:javascript
运行
复制
awk '
{
  gsub(/[^/]*\/trunk/,OFS"&")
  sub(/^ /,"")
  sub(/\//,OFS"&")
  gsub(/ +[^/]*\/trunk\/[^[:space:]]+/,"\n&")
  sub(/\n/,OFS)
  gsub(/\n /,ORS)
  gsub(/\/trunk/,OFS"&")
  sub(/[[:space:]]+/,OFS)
}
1
'  Input_file

解释:添加了上面的详细说明。

代码语言:javascript
运行
复制
awk '                                            ##Starting awk program from here.
{
  gsub(/[^/]*\/trunk/,OFS"&")                    ##Globally substituting everything from / to till next / followed by trunk/ with space and matched value.
  sub(/^ /,"")                                   ##Substituting starting space with NULL here.
  sub(/\//,OFS"&")                               ##Substituting first / with space / here.
  gsub(/ +[^/]*\/trunk\/[^[:space:]]+/,"\n&")    ##Globally substituting spaces followed by everything till / trunk till space comes with new line and matched values.
  sub(/\n/,OFS)                                  ##Substituting new line with space.
  gsub(/\n /,ORS)                                ##Globally substituting new line space with ORS.
  gsub(/\/trunk/,OFS"&")                         ##Globally substituting /trunk with OFS and matched value.
  sub(/[[:space:]]+/,OFS)                        ##Substituting spaces with OFS here.
}
1                                                ##Printing edited/non-edited line here.
'  Input_file                                    ##Mentioning Input_file name here.

在显示的示例中,请尝试遵循awk代码。

代码语言:javascript
运行
复制
awk '{gsub(/\/trunk/,OFS "&");gsub(/trunk\/[^/]*\//,"&\n")} 1' Input_file
票数 2
EN

Stack Overflow用户

发布于 2021-11-17 13:54:15

与GNU awk一起用于多个字符RS和RT:

代码语言:javascript
运行
复制
$ awk -v RS='([^/]+/){2}[^/\n]+' 'RT{sub("/",OFS,RT); print RT}' file
A trunk/apple
B trunk/apple
Z trunk/orange

我将RS设置为一个regexp,描述您想要匹配的每个字符串,即2次非/s重复,然后是/,然后是非/s的最后一个字符串(输入行上最后一个字符串的非换行符)。RT自动设置为每个匹配的字符串,因此我只需将第一个/更改为空白并打印结果。

如果每条路径并不总是有3层深度,但始终以something/trunk/开头,例如:

代码语言:javascript
运行
复制
$ cat file
A/trunk/apple/banana/B/trunk/apple/Z/trunk/orange

然后:

代码语言:javascript
运行
复制
$ awk -v RS='[^/]+/trunk/' 'RT{if (NR>1) print pfx $0; pfx=gensub("/"," ",1,RT)} END{printf "%s%s", pfx, $0}' file
A trunk/apple/banana/
B trunk/apple/
Z trunk/orange
票数 3
EN

Stack Overflow用户

发布于 2021-11-17 11:13:39

awk中,您可以尝试这个解决方案。它处理了当下一个字符是大写时移除正斜杠的特殊要求。将不会赢得设计奖,但工作。

代码语言:javascript
运行
复制
$ echo "A/trunk/apple/B/trunk/apple/Z/trunk/orange" | 
    awk -F '' '{ x=""; for(i=1;i<=NF;i++){ 
      if($(i+1)~/[A-Z]/&&$i=="/"){$i=""}; 
      if($i~/[A-Z]/){ printf x""$i" "}
      else{ x="\n"; printf $i } }; print "" }'
A /trunk/apple
B /trunk/apple
Z /trunk/orange

也适用于n个单词。实际上,它适用于任何遵循给定模式的东西。

代码语言:javascript
运行
复制
$ echo "A/fruits/apple/mango/B/anything/apple/pear/banana/Z/ball/orange/anything" | 
    awk -F '' '{ x=""; for(i=1;i<=NF;i++){
      if($(i+1)~/[A-Z]/&&$i=="/"){$i=""};
      if($i~/[A-Z]/){ printf x""$i" "}
      else{ x="\n"; printf $i } }; print "" }'
A /fruits/apple/mango
B /anything/apple/pear/banana
Z /ball/orange/anything
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70002557

复制
相关文章

相似问题

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