SED使用变量查找字符串,编辑,然后替换

问题描述:

我遇到一些问题,试图使用SED使用具有正斜杠的变量编辑文件。SED使用变量查找字符串,编辑,然后替换

的文件,我试图编辑“校验”有如下内容...

758f9775093bf885dbc963cba1aec732,/bin/bash 
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf 
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts 
03f670845fe199955f9a0babecbda9a0,/etc/networks 

我要搜索字符串“/斌/庆典”使用一个变量(FILE_PATH =“/斌/ bash“),当我找到该字符串时,将所有内容移除到”,“并替换为”VALID“。

这是我的sed语法和下面的尝试,但是当我尝试使用变量时失败。有什么建议么?

成功不变量

# sed '\/bin\/bash/ s/^.*,/VALID,/g' checksum 
VALID,/bin/bash 
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf 
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts 
03f670845fe199955f9a0babecbda9a0,/etc/networks 

失败可变

# file_path="/bin/bash" 
# echo $file_path 
/bin/bash 

# sed '/$file_path/ s/^.*,/VALID,/g' checksum 
758f9775093bf885dbc963cba1aec732,/bin/bash 
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf 
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts 
03f670845fe199955f9a0babecbda9a0,/etc/networks 

我已经试过包装在引号中的变量,{},仍然有同样的故障:

# sed '/"$file_path"/ s/^.*,/VALID,/g' checksum 
758f9775093bf885dbc963cba1aec732,/bin/bash 
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf 
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts 
03f670845fe199955f9a0babecbda9a0,/etc/networks 

# sed '/{$file_path}/ s/^.*,/VALID,/g' checksum 
758f9775093bf885dbc963cba1aec732,/bin/bash 
1b45027142521f2a1c3d95891770eb47,/etc/grub.conf 
2a34dc288f7994cc7b1b338605ef8775,/etc/hosts 
03f670845fe199955f9a0babecbda9a0,/etc/networks 

我也用“|”作为转义字符。

# sed '|{$file_path}| s|^.*,|VALID,|g' checksum 
sed: -e expression #1, char 1: unknown command: `|' 

有关如何完成此任务的任何建议?

# sed --version 
GNU sed version 4.2.1 

单引号抑制变量替换。试试这个:

sed "\:$file_path: s/^.*,/VALID,/" checksum 

请注意,我已将模式分隔符更改为冒号,以便变量值的斜杠不会结束模式。

+0

完美!我会用这个。当我使用不同的分隔符进行测试时,我发现另一个区域是错误的。我并没有逃避他们。谢谢你的帮助。 – 2014-09-04 18:07:25

要完成@奥加的好答案。保留单引号以避免bash可以解释的特殊字符可能出现的歧义是很有趣的。要做到这一点,你可以简单地关闭sed的块用单引号后重新打开它:

sed '\~'$file_path'~s~^[^,]*~VALID~' checksum 
+0

oogas answer'$ file_path'在双引号内,但与您的不同,它不在任何引号内。如何更好? – 2014-09-04 03:56:52

+0

这不是更好或更坏,这是用单引号来完成的方法。主要兴趣是你可以在单引号之间写任何你想要的东西,而不用bash解释它。 – 2014-09-04 05:40:41

+0

@CasimiretHippolyte我不同意这里。不以避免bash解释不存在的插值元素为代价来引用变量实际上更糟糕。 ':P' – 2014-09-04 06:28:38

只需使用AWK的简单生活:

awk -v fp="$file_path" 'BEGIN{FS=OFS=","} $2==fp{$1="Valid"} 1' file 

,将工作,无论什么内容的file_path,包括/或RE元字符或外壳匹配字符,如果内容部分匹配文件中的任何部分,则不会生成错误匹配。

+0

谢谢你这样做,我总是让我的生活更轻松。我应该开始使用更多的awk,但往往倾向于sed,因为这是我所知道的更多。 – 2014-09-04 18:05:25