首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串片段的条件替换为sed (一行!)

字符串片段的条件替换为sed (一行!)
EN

Stack Overflow用户
提问于 2014-07-03 07:55:15
回答 3查看 1.6K关注 0票数 0

我正在尝试使用sed处理diff操作的结果。这是我的diff输出,我将其输送到sed中。

代码语言:javascript
复制
3d2
< 12-03-22_JET_D_CL_UR_l4053_0061 True_Warning All 9 149261 
62a62
> 13-01-29_VUE_EPM3_v37_CSAV2_0370 True_Warning All 13 22125 
68c68
< 13-05-14_Regular_Front_0062 True_Warning All 13 123383 
---
> 13-05-14_Regular_Front_0062 True_Warning All 21 123383 
119c119
< CADS4_PMP363_20130202_DPH_069 True_Warning All 13 233405 
---
> CADS4_PMP363_20130202_DPH_069 True_Warning All 9 233409 
149c149
< CADS4_PMP363_20130315_Fujifilm_UK_186 True_Warning All 21 18611 
---
> CADS4_PMP363_20130315_Fujifilm_UK_186 True_Warning All 17 18615 

我需要整理不同的字符串,并在字符串中的第三个单词加上“旧”或“新”--取决于第一个字符。到目前为止我最大的努力是

代码语言:javascript
复制
diff new_jumps/true.jump old_jumps/true.jump | sed -n "/^[<>]/ s:\(.\) \(\S\+\) \(.\+\):\2 \1,\3: p" | replace ">" Old | replace "<" New

这给了我这个结果(这正是我想要的)。

代码语言:javascript
复制
12-03-22_JET_D_CL_UR_l4053_0061 New,True_Warning All 9 149261 
13-01-29_VUE_EPM3_v37_CSAV2_0370 Old,True_Warning All 13 22125 
13-05-14_Regular_Front_0062 New,True_Warning All 13 123383 
13-05-14_Regular_Front_0062 Old,True_Warning All 21 123383 
CADS4_PMP363_20130202_DPH_069 New,True_Warning All 13 233405 
CADS4_PMP363_20130202_DPH_069 Old,True_Warning All 9 233409 
CADS4_PMP363_20130315_Fujifilm_UK_186 New,True_Warning All 21 18611 
CADS4_PMP363_20130315_Fujifilm_UK_186 Old,True_Warning All 17 18615 

我的问题是-我如何在sed一行内更改条件表达式,以消除事后使用替换的需要?(我认为这是可能的)预先谢谢

编辑:

我知道,我错过了链接sed表达式的选项,但我想到的是,是否可以在一个替代操作中完成它?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-07-03 08:51:07

使用awk,我得到了更快的响应。试试这个:

代码语言:javascript
复制
diff new_jumps/true.jump old_jumps/true.jump | awk '{ if($1=="<" || $1==">"){($1=="<")?temp="New,":temp="Old,";print $2,temp$3,$4,$5}}'

以下是Jidder提出的另一个解决方案:

代码语言:javascript
复制
awk '/^</{i="old,"}/^>/{i="new,"}i{$2=$2" "i;print;i=0}'
票数 1
EN

Stack Overflow用户

发布于 2014-07-03 08:45:09

通过使用分号(;)向sed添加更多命令,如下所示:

代码语言:javascript
复制
diff new_jumps/true.jump old_jumps/true.jump | sed -n "/^[<>]/ s:\(.\) \(\S\+\) \(.\+\):\2 \1,\3:; s/</New/gp; s/>/Old/gp"
票数 2
EN

Stack Overflow用户

发布于 2014-07-03 16:12:14

@火山口:在sed中有一个一元线的解决方案,但依赖于与外壳的相互作用。如果您只想拥有一个sed替换命令,就不能避免这种行为:您必须将第一个字符出现在行中的信息输出到shell,shell在某种程度上执行到"Old“或"New”字符串的映射,并将结果返回给sed。

所以单线不是单线因为我们必须定义壳中的东西.;)

代码语言:javascript
复制
replace() { if [ "$1" == ">" ] ; then echo -n "Old"; else echo -n "New" ; fi }
export -f replace
sed -n '/^[<>]/ s:\(.\) \(\S\+\) \(.\+\):echo "\2 $(replace \\\1),\3";:ep' yourfile

请注意,替换命令的e标志是GNU扩展,我们在这里使用它来避免显式调用shell。如果不使用GNU,您可以简单地将上面的最后一行替换为以下内容:

代码语言:javascript
复制
sed -n '/^[<>]/ s:\(.\) \(\S\+\) \(.\+\):echo "\2 $(replace \\\1),\3";:p' yourfile | bash

我在这里给出的解决方案受到了that other one的启发。

还请注意,如果您接受将三个字母的标记"Old“和"New”替换为它们的首字母,那么所有这些操作都是可以避免的,因为这样我们就可以灵活地使用y命令首先以tr的方式执行操作,同样:

代码语言:javascript
复制
sed -n '/^[<>]/ y/<>/ON/; s:\(.\) \(\S\+\) \(.\+\):\2 \1,\3:p' yourfile
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24548075

复制
相关文章

相似问题

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