Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 执行递归查找并替换为sed只会更改第一个文件_Macos_Sed_Find_Exec_Xargs - Fatal编程技术网

Macos 执行递归查找并替换为sed只会更改第一个文件

Macos 执行递归查找并替换为sed只会更改第一个文件,macos,sed,find,exec,xargs,Macos,Sed,Find,Exec,Xargs,我试图递归搜索当前目录,在找到的每个.txt文件的第一行执行sed替换 在MacOS上运行以下两个命令之一: find . -name "*.txt" -exec sed -i '' '1 s/([^()]*)//g' {} + 结果也是一样的。只有找到的“第一个”文件才对其执行了sed操作。这似乎是因为sed-i''1s/([^()]*])//g'中的1。奇怪的是,即使这只导致使用第一个文件,它仍然只在该文件的第一行执行sed替换;它应该这样做 如果我将命令更改为此 find . -nam

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

在MacOS上运行以下两个命令之一:

find . -name "*.txt" -exec sed -i '' '1 s/([^()]*)//g' {} + 
结果也是一样的。只有找到的“第一个”文件才对其执行了
sed
操作。这似乎是因为
sed-i''1s/([^()]*])//g'
中的
1
。奇怪的是,即使这只导致使用第一个文件,它仍然只在该文件的第一行执行sed替换;它应该这样做

如果我将命令更改为此

find . -name '*.txt' -print0 | xargs -0 sed -i '' '2 s/([^()]*)//g'
仍然只是更改了第一个文件,但现在第二行有替换文件。那么,我的问题是,为什么这似乎只影响

find . -name '*.txt' -print0
编辑以进行澄清

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

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

每个
.txt
文件都只包含一行:

这个应该留下(这个应该走)

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

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

test1.txt:
这个应该保留(应该保留)

test2.txt:
这应该保持不变

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

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

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

find . -name '*.txt' -print0
给出以下内容(每个内容由一个
\0
空字符分隔)

通过随机更改文件夹和文件名,可以清楚地看出,它始终是上述
\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
将按预期工作。

您认为
'
的作用是什么?你登记seds帮助了吗?如果你移除它会发生什么?MacOs,GNU,您正在使用哪个sed?@Yunnosch我认为有必要使用“”来阻止MacOs创建已编辑文件的备份副本?因此,通过使用“”,我强迫sed以isIf的形式编辑每个文件,如果我正确地告诉您使用MacOs sed,那么我建议您在您的问题中明确地提到这一点。试着找到一个标记来反映这一点。第一个命令末尾的
+
是什么意思?我想如果你用
\相反,它将按预期工作。我不确定为什么
xargs
版本不起作用。谢谢,但在我解释它为什么起作用之前,我不会将其作为答案发布。我对
xargs
之谜有一个部分答案。。。
sed -i '' 1 s/([^()]*)//g ./test1.txt ./test2.txt ./test3.txt ./test4.txt
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