我有一个txt文件,看起来像这样,
1:Ana:apple:08:00:wait
1:Joe:banana:08:30:wait
1:Oscar:orange:08:45:ready
1:Monica:apple:08:50:ready
1:Mark::orange:ready
我必须找到仅第一行包含两个单词,“香蕉”和“等等”然后替换整行和$myvar
到目前为止我已经尝试过这段代码,但我认为我在同时匹配 2 个单词时遇到一些问题。
sed -i "0,/banana.wait/c\$myvar" myfile
感谢任何可以帮助我的人
答案1
要让该c
命令仅影响同时包含banana
和的行wait
,请确保跳过与这两个模式不匹配的所有行。您可以使用以下b
命令来执行此操作,该命令将分支到当前行的编辑脚本的末尾:
sed -e '/banana/!b' -e '/wait/!b' -e "c\\$myvar" file
c
如果当前行不匹配banana
或wait
(以任何顺序),则会跳过该命令。
如果顺序很重要(banana
之前wait
),则使用
sed -e '/banana.*wait/!b' -e "c\\$myvar" file
如果匹配整个单词而不是子字符串(即 onlybanana
和 not bananas
)很重要,则将每个单词包装在\<...\>
or中\b...\b
以确保单词边界正确匹配。
请注意双反斜杠,这是在双引号字符串中插入单个反斜杠的方法。单个反斜杠会转义$
in $myvar
,从而防止变量被扩展。
请注意,这需要一个sed
实现,例如 GNU sed
,它允许输入命令文本c
而不需要前面的换行符。
这进一步假设值中的任何文字换行符$myvar
都使用文字反斜杠字符进行转义,如
myvar='hello\
world'
如果输入数据被构造为带有字段的记录,并且如果哪个字段是什么banana
以及哪个字段很重要wait
,则可以正确解析记录,可能使用awk
,如
value=$myvar awk -F : '$3 == "banana" && $NF == "wait" { $0 = ENVIRON["value"] }; 1' file
这显式测试了第三个字段banana
(精确字符串测试而不是正则表达式子字符串测试),最后一个字段并用wait
给定值替换当前记录,作为环境变量传入value
。
答案2
框架挑战:sed 不是解决此问题的最佳工具。
在 Awk 中,我们可以不考虑顺序来组合匹配,即/banana/ && /wait/
.
或者我们可以精确匹配特定字段
awk -F: -v repl="$myvar" -e '$3 == "banana" && $6 == "wait" { $0 = repl } {print}'