【问题标题】:find and replace within file在文件中查找和替换
【发布时间】:2011-07-18 00:19:53
【问题描述】:

我需要搜索类似的模式:

timeouts = {default = 3.0; };

替换成

timeouts = {default = 3000.0;.... }; 

即将超时乘以 1000。

有没有办法对目录中的所有文件执行此操作

EDIT :

请注意,有些文件是目录中的符号链接。有没有办法也为符号链接完成此操作?

请注意,文件中也存在超时作为子字符串,所以我想确保只有这一行被替换。使用 sed awk perl 可以接受任何解决方案。

【问题讨论】:

  • -1:你试过什么?什么不起作用?
  • 目录中的一些文件是符号链接。我们如何为链接做到这一点

标签: regex perl replace sed awk


【解决方案1】:

试试这个:

for f in *
do
    sed -i 's/\(timeouts = {default = [0-9]\+\)\(\.[0-9]\+;\)\( };\)/\1000\2....\3/' "$f" 
done

它将为当前目录中的每个文件进行替换。某些版本的sed 需要在-i 选项之后使用备份扩展名。您可以像这样提供:

sed -i .bak ...

某些版本不支持就地编辑。你可以这样做:

sed '...' "$f" > tmpfile && mv tmpfile "$f"

请注意,这显然不是实际乘以 1000,因此如果数字是 3.1,它将变为“3000.1”而不是 3100.0

【讨论】:

  • 我认为“....”可以是任何文本,例如其他超时。不是字面上的'....'。
  • @dogbane:有可能,但之前没有出现,后来出现了。
  • 实际上目录中的一些文件是符号链接。我们如何为链接做到这一点?
  • @TopCoder: sed -i '...' "$(readlink -e "$f")"sed '...' "$f" > tmpfile && mv tmpfile "$(readlink -e "$f")"
【解决方案2】:

你可以这样做

perl -pi -e 's/(timeouts\s*=\s*\{default\s*=\s*)([0-9.-]+)/print $1; $2*1000/e' *

【讨论】:

    【解决方案3】:

    对于您决定使用上述哪种解决方案的一个建议 - 考虑如何重构以避免再次修改所有这些文件以进行此类更改可能是值得的。

    • 所有这些脚本都具有相似的功能吗?
    • 您能否创建一个它们都将用于共享子例程的模块?
    • 在模块中,您能否有一条线来让您拥有一个乘数?

    对我来说,每当我需要对多个文件进行类似更改时,现在是lazy 的最佳时机,可以节省自己的时间和以后的维护问题。

    【讨论】:

      【解决方案4】:
      $ perl -pi.bak -e 's/\w+\s*=\s*{\s*\w+\s*=\s*\K(-?[0-9.]+)/sprintf "%0.1f", 1000 * $1/eg' *
      

      注意事项:

      • 正则表达式只匹配数字(参见 perlre 中的 \K
      • /e 表示替换已评估
      • 我在替换中包含一个sprintf,以防您需要更好地控制格式
      • Perl 的-i 可以对一堆文件进行操作

      编辑

      有人指出,有些文件是杂乱无章的链接。鉴于此过程不是幂等的(在同一个文件上运行两次是不好的),您最好生成一个唯一的文件列表,以防其中一个链接指向出现在列表中其他位置的文件。下面是一个 find 的示例,尽管预先存在的列表的代码应该很明显。

      $ find -L . -type f -exec realpath {} \; | sort -u | xargs -d '\n' perl ...
      

      (假设您的文件名都不包含换行符!)

      【讨论】:

      • 一些文件是符号链接。我们如何使用相同的解决方案?
      • 您首先需要将符号链接名称映射到真实文件名 - 这可以通过 Cwd 模块中的 realpath 完成。
      猜你喜欢
      • 1970-01-01
      • 2014-08-17
      • 2011-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多