Bash脚本:如果行以(或匹配)另一个string开头,则replace(或删除)文件中的string

假设这样的ini风格的文件,

[Group] Icon=xxx.ico Title=An Image Editor Description=Manipulates .ico, .png and .jpeg images 

我只想在以(或匹配)开头的行中replace/删除“.ico”“Icon =”

我正在尝试这个:

 oldline="`cat "$file" | grep "Icon="`" newline="`echo "$oldline" | tr ".ico" ".png"`" cat "$oldfile" | tr "$oldline" "$newline" > $file 

然后我意识到, tr完全不同于我的想法。 它不是一个传统的“取代这个”function。 所以我想正确的方法是使用sed 。 但:

  • 我以前从来没有用过sed 。 不知道它是如何工作的。 这是否过分了?
  • 如果最有说服力的方式是真的使用sed ,鉴于它是如此强大,是否有任何优雅的方式来完成这个,而不是这个“取行 – >修改行 – >replaceoldline换文件”方法?

笔记:

  • 我不能replace全球的“.ico”,我知道这将是一个很容易,我必须限制replace到图标行,否则描述行也将被改变。
  • 我在Linux中是shell脚本的新手,所以我不仅要看到解决scheme本身,还要“正确”的方式来做到这一点。 优雅,易读,常规等

提前致谢!

编辑:

感谢你们! 这是最后的脚本,作为参考:

 #! /bin/bash # Fix the following WARNING in ~/.xsession-errors # gnome-session[2035]: EggSMClient-WARNING: Desktop file '/home/xxx/.config/autostart/skype.desktop' has malformed Icon key 'skype.png'(should not include extension) file="$HOME/.config/autostart/skype.desktop" if [ -f "$file" ] ; then if `cat "$file" | grep "Icon=" | grep -q ".png"` ; then sed -i.bak '/^Icon=/s/\.png$//' "$file" cp "$file" "$PWD" cp "${file}.bak" "$PWD" else echo "Nothing to fix! (maybe fixed already?)" fi else echo "Skype not installed (yet...)" fi 

比我原来的更光滑! 我唯一感到遗憾的是, sed备份不会保留原始文件时间戳。 但我可以忍受

而且,为了logging,是的,我创build了这个脚本来修复Skype包装中的一个实际“bug”。

像sed中的以下内容应该做你需要的。 首先我们检查一下这行是否以Icon=开始,如果是,那么我们运行s命令(即替换)。

 sed -i '/^Icon=/s/\.ico$/.png/' file 

编辑:上面的sed脚本也可以这样写:

 /^Icon=/ { # Only run the following block when this matches s/\.ico$/.png/ # Substitute '.ico' at the end of the line with '.png' } 

有关如何限制命令运行的详细信息,请参阅此页面 。

sed很容易处理。 这里有一个方法:

 sed 's/^\(Icon=.*\)\.ico$/\1.png/' 

默认情况下,sed一次处理文件中的每一行。 '/…/…/'将在第一个参数上进行正则表达式匹配,并将其替换为第二个参数。 \ 1代表与第一组匹配的所有内容,这是由括号划定的。 你必须用\ \来逃跑。

上面的工作是作为管道的一部分,但是你可以像这样添加一个'-i'标志

 sed -i 's/^\(Icon=.*\)\.ico$/\1.png/' input.txt 

让它替换文件input.txt。 不要添加,直到你有一点测试你的sed脚本。