查找与模式匹配的文件,替换字符串,然后将输出与原始文件进行比较,命令失败

Posted

技术标签:

【中文标题】查找与模式匹配的文件,替换字符串,然后将输出与原始文件进行比较,命令失败【英文标题】:Find files matching a pattern, replace strings and then diff the output with original, command fails 【发布时间】:2021-11-16 09:14:32 【问题描述】:

我正在尝试查找名称为.* 的文件并在匹配的文件上运行 sed,然后通过管道传输到 diff 以查看更改的内容。

但是命令失败。如果我删除管道差异,很高兴输出结果。为什么差异失败?有没有更好的方法来做到这一点?

> find -type f -name "names.*" -printf '%p' -exec sed 's/Cow/Kitten'  | diff  - \;
diff: extra operand ';'
diff: Try 'diff --help' for more information.
find: missing argument to \-exec\'`

【问题讨论】:

【参考方案1】:

需要一个 shell 来做你想做的事,就像这样。

find -type f -name "names.*" -exec sh -c '
  for f; do 
    sed 's/Cow/Kitten/' "$f" | diff "$f" -
done' _  \;

一体式

find -type f -name "names.*" -exec sh -c 'for f; do sed 's/Cow/Kitten/' "$f" | diff "$f" -; done' _  \;

见understanding-the-exec-option-of-find

或者使用while + read 循环和Process Substitution。

#!/usr/bin/env bash

while IFS= read -rd '' files; do
  sed 's/Cow/Kitten/' "$files" | diff "$files" -
done < <(find -type f -name "names.*" -print0)

后一个脚本是空格/制表符/换行符安全的,但严格来说是bash,而前一个脚本是 POSIX sh。 (将/应该与任何 POSIX 兼容的 shell 一起工作/执行。)

见How can I find and safely handle file names containing newlines, spaces or both?

见How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?

【讨论】:

以上是关于查找与模式匹配的文件,替换字符串,然后将输出与原始文件进行比较,命令失败的主要内容,如果未能解决你的问题,请参考以下文章

力扣——查找和替换模式

vim 查找与替换

如何使用与号 (&) 替换匹配模式中的字符

将lookbehind模式与匹配的正则表达式搜索模式分组以作为整体替换

Java正则表达式入门

Java 正则简单用法