macos - 使用 sed 执行递归查找和替换仅更改第一个文件

标签 macos sed find exec xargs

我尝试递归搜索当前目录,对找到的每个 .txt 文件的第一行执行 sed 替换。

在 MacOS 上运行这 2 个命令之一:

find . -name "*.txt" -exec sed -i '' '1 s/([^()]*)//g' {} + 
find . -name '*.txt' -print0 | xargs -0 sed -i '' '1 s/([^()]*)//g'

导致相同的结果。只有找到的“第一个”文件才会对其执行 sed 操作。这似乎是由于 sed -i '' '1 s/([^()]*)//g' 中的 1 造成的。奇怪的是,即使这只会导致使用第一个文件,它仍然只对该文件的第一行执行 sed 替换;这是应该的。

如果我将命令更改为这个

find . -name '*.txt' -print0 | xargs -0 sed -i '' '2 s/([^()]*)//g'

仍然只有第一个文件发生了变化,但现在第二行有了替换。那么,我的问题是为什么这似乎只影响返回的第一个文件

find . -name '*.txt' -print0

编辑以澄清

我应该通过逐步重新创建问题来澄清我所说的只有“第一个”文件才对其执行 sed 操作的确切含义。首先,

这是文件夹层次结构(注意“文件夹 1”中的空格):

.
├── folder\ 1
│   └── test1.txt
├── folder2
│   └── test2.txt
├── folder3
│   └── test3.txt
└── folder4
    └── test4.txt

每个 .txt 文件都包含这一行,而且只有这一行:

这应该保留(这应该消失)

当运行上述任一命令时,文件 test2.txt 被更改,问题是它是唯一被更改的文件!

现在,这些文件包含以下内容:

test1.txt:这应该保留(这应该消失)

test2.txt:这应该保留

test3.txt:这应该保留(这应该消失)

test4.txt:这应该保留(这应该消失)

我相信这是因为命令的第一部分,例如

find . -name '*.txt' -print0

给出以下内容(每个内容由 \0 空字符分隔)

./folder2/test2.txt./folder3/test3.txt./folder4/test4.txt./folder 1/test1.txt

通过随机更改文件夹和文件名,很明显,上面 \0 分隔列表中的第一个文件始终会被更改。

所以问题仍然存在,对 sed 的调用是什么阻止了对所有文件的调用?

谢谢!

最佳答案

我想 Beta 已经回答了有关第一个命令的问题,让我回答第二个命令。

尝试将 -t (测试)选项放入 xargs 并查看命令行 展开:

find . -name '*.txt' -print0 | xargs -0 -t sed -i '' '1 s/([^()]*)//g'

它会输出如下内容:

sed -i '' 1 s/([^()]*)//g ./test1.txt ./test2.txt ./test3.txt ./test4.txt

xargs的默认行为是执行指定的命令 (在本例中为 sed)立即从标准中读取所有参数 输入。
此外,sed 不会重置多个输入文件和 s 命令之间的行编号 以上仅适用于第一个文件。

您可以使用 -l1 选项更改 xargs 的行为:

find . -name '*.txt' -print0 | xargs -0 -l1 -t sed '1 s/([^()]*)//g'

输出:

sed -i '' 1 s/([^()]*)//g ./test1.txt
sed -i '' 1 s/([^()]*)//g ./test2.txt
sed -i '' 1 s/([^()]*)//g ./test3.txt
sed -i '' 1 s/([^()]*)//g ./test4.txt

然后 sed 将按预期工作。

关于macos - 使用 sed 执行递归查找和替换仅更改第一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59740364/

相关文章:

cocoa - 在 Objective-C 中转换 FLV 文件

macos - 使用不同的命令行参数/参数关闭和启动

linux - 需要有关如何从 bash 脚本中调用 .sed 文件的帮助

linux - 如何在 unix 中格式化带有目录名的文件列表?

macos - 当光标位于 NSSearchField 上时显示消息

macos - 如何从 Mac 访问 docker 容器 `localhost`?

Linux:向文件添加带有字符和递增数字的新行

regex - sed 替换所有字符直到第一个空格

c++ - 以 vector 为键操作的 map 查找

linux - 定位无法搜索/开发?