如何使用通过 xargs 管道传输的 find 输出在文件列表上运行多个 sed 命令

如何使用通过 xargs 管道传输的 find 输出在文件列表上运行多个 sed 命令

这是我尝试过的:

find . -name *.sv | xargs sed -i -e '<command>' -e '<command>'

这是行不通的。对每个文件使用完全相同的命令仍然有效。

谢谢您的帮助。

答案1

要强制一次xargs仅执行一个文件,请使用with 。您还应该从using传递路径名并使用 with 接收它们(如果您的and支持这些非标准选项),以便正确处理包含空格等的路径名。您可能还需要指定您正在查找常规文件(而不是目录等),并且您肯定需要引用该 shell glob(或者它可能会扩展到当前目录中的任何匹配文件名):sed-n 1xargsfind-print0xargs-0findxargs

find . -type f -name '*.sv' -print0 | xargs -0 -n 1 sed -i -e '<command>' -e '<command>'

或者,只需使用find

find . -type f -name '*.sv' -exec sed -i -e '<command>' -e '<command>' {} ';'

有关的:


不使用find,而是使用执行后**可用的通配模式(“递归”向下匹配到子目录)的解决方案:bashshopt -s globstar

shopt -s globstar dotglob nullglob
for pathname in ./**/*.sv; do
    if [[ -f "$pathname" ]] && [[ ! -h "$pathname" ]]; then
        sed -i -e '<command> -e '<command>' "$pathname"
    fi
done

此循环循环遍历具有文件名后缀的所有文件.sv,并在应用命令之前测试每个匹配的名称是否是常规文件(我们必须单独测试以! -h确保它不是到常规文件的符号链接)sed。 shell 选项启用**( )的使用globstar、隐藏名称的匹配 ( dotglob),如果不匹配则完全删除模式 ( nullglob)。

或者,使用默认启用zsh的 shell **,并且可以使用“glob 限定符”来完成大部分bash必须显式执行的“额外”工作:

for pathname in ./**/.sv(.DN); do
    sed -i -e '<command> -e '<command>' "$pathname"
done

glob 限定符(.DN)修改前面的通配模式,以便它仅匹配常规文件,匹配隐藏名称,如果根本不匹配,则扩展为空。

答案2

这是另一种对我有用的方法:

find -name "*.fail" | xargs -L 1 sed -i -e 's/cse/ecs/g' -e 's/trex/dino/g'

答案3

这对我有用 grep -rl foo | xargs sed -i 's/foo/bar'

相关内容