在每次更换之前让 sed 要求确认?

Yuv*_*uvi 41 vim sed

有没有办法让 sed 在每次更换之前要求我确认?在 vim 中使用 replace 时类似于 'c' 的东西。

sed 会这样做吗?

Kus*_*nda 44

这样做sed可能是不可能的,因为它是一个非交互式流编辑器。包装sed在脚本中需要太多的思考。使用以下方法更容易vim

vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' file.in
Run Code Online (Sandbox Code Playgroud)

由于在下面的评论中提到了它,下面是如何在当前目录中匹配特定文件名通配模式的多个文件上使用它:

for fname in file*.txt; do
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
Run Code Online (Sandbox Code Playgroud)

或者,如果在执行替换之前首先要确保文件确实包含与给定模式匹配的行,

for fname in file*.txt; do
    grep -q 'PATTERN' "$fname" &&
    vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' "$fname"
done
Run Code Online (Sandbox Code Playgroud)

上面的两个 shell 循环修改为find执行相同操作的命令,但是对于某个top-dir目录中或某个目录下的所有具有特定名称的文件,

find top-dir -type f -name 'file*.txt' \
    -exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
Run Code Online (Sandbox Code Playgroud)
find top-dir -type f -name 'file*.txt' \
    -exec grep -q 'PATTERN' {} \; \
    -exec vim -c '%s/PATTERN/REPLACEMENT/gc' -c 'wq' {} \;
Run Code Online (Sandbox Code Playgroud)

或者,使用原始 shell 循环并将find路径名输入其中:

find top-dir -type f -name 'file*.txt' -exec sh -c '
    for pathname do
        vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
    done' sh {} +
Run Code Online (Sandbox Code Playgroud)
find top-dir -type f -name 'file*.txt' -exec sh -c '
    for pathname do
        grep -q "PATTERN" "$pathname" &&
        vim -c "%s/PATTERN/REPLACEMENT/gc" -c "wq" "$pathname"
    done' sh {} +
Run Code Online (Sandbox Code Playgroud)

无论如何,不想做这样的事情,for filename in $( grep -rl ... )因为

  1. 它需要grep在开始循环的第一次迭代之前完成运行,这是不优雅的,并且
  2. 返回的路径名将grep被拆分为空格上的单词,并且这些单词将进行文件名通配(这会取消包含空格和特殊字符的路径名)。

有关的:

  • `for i in $(grep -rl "old"); do vim -c "%s/old/new/gc" -c "wq" "$i"; 完成` (10认同)
  • `sed` 的优点是它可以操作多个文件,例如,`sed -i 's/old/new/g' /path/to/*.txt` 或类似的东西。 (2认同)

Kev*_*n M 7

You can get this by doing such:

:%s/OLD_TEXT/NEW_TEXT/gc
Run Code Online (Sandbox Code Playgroud)

Specifically, adding the c after the third delimiter.

Note that the 'c' option only works in Vim; you won't be able to use it with sed at the command line.

  • 澄清一下:这仅适用于 Vim,不适用于常规命令行 `sed`。 (4认同)