2013-03-29 90 views
2

目前,我有一个全功能的sed命令,增加了一个项目,以下列方式具体的文本文件列表...条件SED替代

ITEMS="$ITEM1 $ITEM2 $ITEM3" 

成为下,当我们要插入$ITEM4 ...

ITEMS="$ITEM1 $ITEM2 $ITEM3 $ITEM4" 

列表中的项目数量是未知的;它是动态的。该文本中的美元符号和引号应从字面上理解。

我用下面的命令来完成除了列表(可变$itemNum在别处分配)...

sed "/^\s*ITEMS=/s/\"$/ \$ITEM$itemNum&/" file.txt 

这一切呢,当然是找到以ITEMS=线(也可能是与领先的空格),并将该行中的最后一个双引号替换为空格加上所需的项目加双引号(将替换的双引号放回原位)。但是,我有一个附加的情况下ITEMS列表可能是空的,像这样......

ITEMS="" 

在这种情况下,我的命令将插入$ITEM4在列表像这样结束......

ITEMS=" $ITEM4" 

不过,我想我的命令能够占到一个空列表,而不是把主要空间时,列表确实是空的,所以它只是看起来像......

ITEMS="$ITEM4" 

如何改变我现有的命令以最好地完成此操作?

在这种情况下

回答

2

拍摄被摄对象为指导,在这里是用sed做有条件的一种方法:

sed -e '/^\s*ITEMS=/{s/=""/="$ITEM'"$itemNum"'"/;t;s/"$/ $ITEM'"$itemNum&/;}" file.txt 

主要变化是我们尝试先用空引号(“”)替换。如果成功,则条件分支t将我们发送到脚本的末尾,绕过另一个替换。如果第一次失败,则仅发生第二次替换。我已经改变了引用来摆脱一些“倾斜的牙签”,但它大约是您原始命令的66%。

编辑:由OP的请求“倚牙签”的事情

原来放在双引号整个sed脚本行,以便所有的“最$必须与反斜杠转义重写我的版本一样,看起来像。这样的:

sed -e "/^\s*ITEMS=/{s/=\"\"/=\"\$ITEM$itemNum\"/;t;s/\"$/ \$ITEM$itemNum&/;}" file.txt 

我只是觉得所有的反斜线分心,所以我把尽可能多的成单引号尽我所能,只留下$ itemNum在双引号。在shell脚本中,如果两个字符串相邻,它们会粘在一起,因此var1=QRS; var2='ABC'$var1'XYZ'将var2设置为'ABCQRSXYZ' - 如果您认为变量可能包含空格,那么最好引用它:var1=QRS; var2='ABC'"$var1"'XYZ'(no space间“‘和’”在那里。

+0

谢谢。请问你请简要解释一下你的命令是如何构造的,关于单引号和双引号的各种用法?就像你如何使用它们来说明问题的语法一样?还有,你会介意添加一个使用所有倾斜牙签,只是为了我的学习吗? – user2150250

+0

谢谢你的解释,他们帮助很大。 – user2150250

1

,AWK更加灵活:

awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1' file 

测试:

kent$  itemNum=4  
kent$ echo 'ITEMS=""'|awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1' 
ITEMS="$ITEM4" 
kent$ echo 'ITEMS="$ITEM1 $ITEM2 $ITEM3"'|awk -F'"' -vn="$itemNum" '/^\s*ITEMS=/{sub(/"$/,($2?" ":"")"$ITEM"n"&")}1'              
ITEMS="$ITEM1 $ITEM2 $ITEM3 $ITEM4" 
+0

再次感谢肯特。这不工作用awk,但是你觉得有一种方法,使用SED做到这一点和'?'元字符吧? – user2150250