在bash中编辑文件的几行

时间:2014-07-01 09:31:45

标签: regex macos sed

您好我想以这种方式解析包含设置的bash中的js文件:

user_pref("network.proxy.socks", "127.0.0.1");
user_pref("network.proxy.socks_port", 9150);
user_pref("network.proxy.type", 1);
  • 如果这些行不存在,则应创建它(>> append)。
  • 如果已经使用这些值设置了行:不执行任何操作。
  • 如果行已设置了不同的值,请将其更改为值&#34; 127.0.0.1&#34; 9150 1 < / strong>

到目前为止,我可以执行第1点和第2点,但我在第3点挣扎。 我相信它可以通过使用bash条件来实现,并且&#39; sed &#39;正则表达式。 任何人(正则表达专家)能帮助我吗?


快速介绍我的问题:

我正在OS X上编写一个bash脚本,并在127.0.0.1:9150上监听socks5。 我想通过编辑 prefs.js 文件(相当于url about:config )为Firefox设置这些设置。用于此的GUI是首选项/高级/网络/连接设置/手动代理/ Socks5

仅供参考,这是我的剧本,缺少的部分是 ### MISSING PART ###

function sshD
{
    pkill firefox #Kill existing instance(s) of Firefox
    #Create HTTP Proxy via SSH Tunnel
    ssh -Cc blowfish -D9150 -Nf myuser@mydomain
    fxpref="$HOME/Library/Application Support/Firefox/Profiles/"; fxpref="$fxpref`ls "$fxpref" | awk 'NR==1'`/prefs.js"
    test ! -f "$fxpref".backup && cp "$fxpref" "$fxpref".backup
    proxypref=`cat "$fxpref" | grep proxy`
    ###MISSING PART###
    /Applications/Firefox.app/Contents/MacOS/firefox-bin -private > /dev/null 2>&1 &
}

2 个答案:

答案 0 :(得分:4)

适用于FreeBSD sed(OS X)以及GNU sed(Linux)的解决方案 - 该方法的基础知识基于@anishsane's answer

注意:

  • 假设保留输入文件中原始的首选顺序,以简化解决方案。
  • 因此,此解决方案有效 first 从输入文件中删除现有的感兴趣的首选项(如果有的话),然后将所需的(新)值附加到
sed -En '/user_pref\("network\.proxy\.(socks|socks_port|type)"/!p
        $ a\
user_pref("network.proxy.socks", "127.0.0.1");\
user_pref("network.proxy.socks_port", 9150);\
user_pref("network.proxy.type", 1);
        ' prefs.js

注意:上面只是将结果输出到stdout;如果您想用结果替换输入文件,将原件保存到*.backup,请使用:

sed -En -i'.backup' ...

说明:

  • -E启用了对扩展正则表达式的支持,这增加了|等重要功能以进行更改(除了需要更少的转义)。
  • -n抑制(可能已修改的)输入行的默认输出,因此只有显式输出函数(如pai)才会生成输出。
  • /user_pref\("network\.proxy\.(socks|socks_port|type)"/!p会导致所有不包含感兴趣的首选项的行被打印出来;换言之:包含感兴趣的首选项(及其当前值)的现有行实际上已已删除
  • $ a在输入的 last 行($)之后将文本附加到输出,此处只输出所需的 new < / em> values。
  • 总体而言,\ - 转义的换行符经过精心设置,以使FreeBSD sed满意 - 纯粹的GNU sed解决方案会更简单;请参阅https://stackoverflow.com/a/24276470/45375了解两种实现之间的差异。

答案 1 :(得分:1)

我相信firefox的pref.js是逐行阅读的。这些偏好的顺序并不重要。

所以,这应该有效:

sed '/user_pref("network.proxy.\(socks\|socks_port\|type\)"/d;
        $auser_pref("network.proxy.socks", "127.0.0.1");\nuser_pref("network.proxy.socks_port", 9150);\nuser_pref("network.proxy.type", 1);' pref.js