目前,我有一个功能齐全的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"
我怎样才能改变现有命令以达到最佳效果?
答案 0 :(得分: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'
(“和”之间没有空格。
答案 1 :(得分: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"