如何用sed替换不包含其他字符串的字符串?

时间:2019-02-12 17:32:05

标签: ruby sed delimiter-separated-values

我正在尝试替换目录中的路径。

到目前为止,我已经尝试在目录中的每个文件上使用它,但是,我遇到了语法错误:

sed -i \"/'#{CREW_PREFIX}'/\\\!s,/usr,#{CREW_PREFIX},g\" \${file};

这是语法错误:

sed: -e expression #1, char 3: unknown command: `u'

示例输入:

prop.ppd_search_path = '/usr/share;/usr/local/share;/usr/lib;/usr/local/lib;/usr/libexec;/opt;/usr/lib64'

示例输出:

prop.ppd_search_path = '/usr/local/share;/usr/local/share;/usr/local/lib;/usr/local/lib;/usr/local/libexec;/opt;/usr/local/lib64'

我在做什么错了?

该行需要匹配/usr,但不必匹配/usr/local,否则输出的路径将类似于/usr/local/local。 最重要的是,替换需要从Ruby变量中读取, 因此它可能是/usr/local(默认情况下),或者完全不同 像/foo/bar这样的路径。

用例:

在目录(HP Linux Printing System源代码)中,有数千个硬编码路径指向只读路径(在Chrome OS中为/usr)。我试图用用户定义的前缀(默认为/usr)替换/usr/local的所有实例,而忽略包含用户定义的前缀的行。用户定义的前缀位于Ruby脚本中,并且必须包含在Ruby变量(#{CREW_PREFIX})中。这就是我想要做的:

  def self.patch
    # Fix hardcoded file directories
    system "for file in \$(find . -type f); do
              sed -i 's,/etc,#{CREW_PREFIX}&,g' \${file};
              sed -i 's,/usr/share,#{CREW_PREFIX}/share,g' \${file};
              sed -i 's,/usr/include,#{CREW_PREFIX}/include,g' \${file};
              sed -i 's,/usr/lib,#{CREW_LIB_PREFIX},g' \${file};
              sed -i 's,/var,#{CREW_PREFIX}&,g' \${file};
              sed -i 's,/usr/bin,#{CREW_PREFIX}/bin,g' \${file};
              sed -i 's,#{CREW_PREFIX}/bin/env,/usr/bin/env,g' \${file};
              sed -i 's,#{CREW_PREFIX}/etc/os-release,/etc/os-release,g' \${file};
              sed -i \"/'#{CREW_PREFIX}'/\\\!s,/usr,#{CREW_PREFIX},g\" \${file};
            done"
  end

但是,路径包含斜杠,这使sed给出未知的命令错误:

sed: -e expression #1, char 3: unknown command: `u'

我找不到另一个包含/所具有功能的分隔符。

这就是我要处理的:

chronos@localhost ~/Downloads/tarballs/hplip-3.19.1 $ grep -R /usr ./*/ > file; du -sh file
40K     file

如果/usr实例所在的行与{{1}的值也不匹配,我需要#{CREW_PREFIX}的所有那些实例成为值/usr(可变) }。

1 个答案:

答案 0 :(得分:2)

$ cat file
./configure --prefix=/usr --enable-foo --disable-bar
./configure --prefix=/usr/local --enable-foo --disable-bar

$ var='/foo/bar'; sed 's:/usr/local:\n:g; s:/usr:'"$var"':; s:\n:/usr/local:g' file
./configure --prefix=/foo/bar --enable-foo --disable-bar
./configure --prefix=/usr/local --enable-foo --disable-bar