使用Regex替换或追加文件中的行| Linux Shell脚本
发布时间:2020-12-14 01:20:28 所属栏目:Linux 来源:网络整理
导读:我试图在一个看起来像这样的文件上找到正确的命令来执行:(即.cshrc文件) setenv BLAH foo 我需要命令来替换检测到字符串BLAH的行并替换整行,如下所示: setenv BLAH newfoo 如果文件中不存在BLAH,则将其附加到文件中. 我已经玩过这样的sed,但这并没有实现我
我试图在一个看起来像这样的文件上找到正确的命令来执行:(即.cshrc文件)
setenv BLAH foo 我需要命令来替换检测到字符串BLAH的行并替换整行,如下所示: setenv BLAH newfoo 如果文件中不存在BLAH,则将其附加到文件中. 我已经玩过这样的sed,但这并没有实现我的目标. sed 's/^.*?BLAH.*/setenv BLAH newfoo/g' text.txt > text.tmp && mv text.tmp text.txt 我也玩过awk并且似乎无法使命令正常工作我想要它. awk -v s="setenv BLAH newfoo" '/^BLAH/{f=1;$0=s}7;END{if(!f)print s}' text.txt > text.tmp && mv text.tmp text.txt 关于如何实现这一点的任何想法都会很棒. UPDATE 我试图让这个脚本按预期工作. 脚本 ARG1="$1" sed -i "/BLAH/s/^.*$/setenv ${ENV_KEY} ${ENV_VAL}/g" file.txt # If the BLAH keyword isnt there,append the file then. grep -v -q "BLAH" file.txt && echo "setenv BLAH ${ARG1}" >> file.txt file.txt(默认) setenv BLAH randomstring 脚本的用法 script.sh newvalue file.txt(结果) setenv BLAH newvalue 目前,脚本似乎每次都附加文件.我还尝试了一些其他的建议,但我不能让他们接受sed字符串中的传入arg1值. 解决方法
介绍
这可以通过这个sed脚本完成: sed '/BLAH/{s/ w+$/ newfoo/;h};${x;/BLAH/ba;x;s/$/nsetenv BLAH newfoo/;x;:a;x}' 说明 sed -e ' /^(|.*W)BLAH(W.*|)$/{ # lines matching word BLAH s/ w+$/ newfoo/; # replace last word by "newfoo" h; # Store for not adding them at end of file }; ${ # On last line... x; # Swap stored line with current line /BLAH/ba; # if match,branch to label a: x; # Swap back s/$/nsetenv BLAH newfoo/; # Replace end of line with newline... x; # Swap again :a; # Label a: x # Swap back }' 您可以使用就地编辑开关: sed -e'/BLAH/{h};${x;/BLAH/ba;x;s/$/nsetenv BLAH newfoo/;x;:a;x}' -i text.txt 为了更准确,搜索分隔的单词BLAH: sed -e ' /^(.*W|)BLAH(W.*|)$/{h}; # Store lines matching word BLAH ${ # On last line... x; # Swap stored line with current line /./ba; # if match,branch to label a: x; # Swap back s/$/nsetenv BLAH newfoo/; # Replace end of line with newline... x; # Swap again :a; # Label a: x # Swap back }' <(echo BLAH=foo;seq 1 4) BLAH=foo 1 2 3 4 而 sed -e ' /^(.*W|)BLAH(W.*|)$/{h}; # Store lines matching word BLAH ${ # On last line... x; # Swap stored line with current line /./ba; # if match,branch to label a: x; # Swap back s/$/nsetenv BLAH newfoo/; # Replace end of line with newline... x; # Swap again :a; # Label a: x # Swap back }' <(echo BLAHBLAH=foo;seq 1 4) BLAHBLAH=foo 1 2 3 4 setenv BLAH newfoo 您可能会看到第二个BLAH被替换为..这可以完成,因为如果未找到1st,则交换空间为空.因此,如果至少有一个字符,这意味着第一个确实发生了. 清洁和脚本 有一种方法可以使它更具脚本化: sedcmd='/^(.*W|)%s(W.*|)$/{s/ w+$/ %s/;h};' sedcmd+='${x;/./ba;x;s/$/nsetenv %s %s/;x;:a;x}' varnam=BLAH varcnt=foo filnam=/tmp/file.txt printf -v sedcmd "$sedcmd" ${varnam} ${varcnt} ${varnam} ${varcnt} sed -e "$sedcmd" -i "$filnam" 你可以删除最后一行的-i开关…… 您可以通过运行来尝试: sed -e "$sedcmd" <(echo setenv BLAH oldfoo;seq 1 4) setenv BLAH foo 1 2 3 4 sed -e "$sedcmd" <(echo setenv BLAHBLAH oldfoo;seq 1 4) setenv BLAHBLAH oldfoo 1 2 3 4 setenv BLAH foo (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |