find . -name "*.txt" -print | xargs sed -i 's/this/that/g'
在OSX上,类似的命令会是什么样子?
OS X使用BSD和GNU工具的混合,所以最好始终检查文档(尽管我曾经发现less
甚至不符合OS X manpage):
sed将在-i
之后的参数作为备份的扩展名。提供一个空字符串(-i ''
)表示不备份。
以下命令应该可以实现:
find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +
-type f
只是个好习惯;如果你给它一个目录,sed会抱怨。
-exec
优先于xargs
;你不需要担心-print0
或其他任何事情。
结尾处的{} +
表示find
将所有结果追加为调用命令的一个实例的参数,而不是针对每个结果重新运行一次。(唯一的例外是当操作系统允许的命令行参数数量达到最大值时;在这种情况下,find将运行多个实例。)
如果出现像“无效的字节序列”之类的错误,可以在命令开头添加LC_ALL=C
来强制使用标准语言环境,像这样:
LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/g {} +
%
符号:sed "s%localhost/site%blah/blah%"
。另一种选择是使用反斜杠转义分隔符:sed "s/localhost\/site/blah\/blah/"
。 - TaylanKammerLC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +
,这对我有用。 - Caio Mar/g
。例如:LC_ALL=C find . -type f -exec sed -i '' s/search/replace/g {} +
。请注意,此命令会批量替换指定目录下所有类型为文件的文本内容中的搜索关键词。 - jamesjara对于Mac电脑,更相似的方法是这样的:
find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"
find . -name '*.php' -print0 | xargs -0 sed -i "" "s/easyform/form360/g"
。 - Andres Ramos作为替代方案,我在Mac OSX 10.7.5上使用了这个。
grep -ilr 'old-word' * | xargs -I@ sed -i '' 's/old-word/new-word/g' @
感谢原作者:Todd Cesere的回答
*
的 grep 的缺点是速度会很慢。考虑使用 -I
来避免处理二进制文件,使用 --exclude-dir
或类似 {dir1,dir2}
的模式。 - zevarito$ grep -ilr 'fastapi' * | xargs -I@ sed -i '' 's/fastapi/flask/g' @
无法正常工作,并输出以下内容:
sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence sed: RE error: illegal byte sequence
- uberrebused
失败了,而不是破坏文件。最好在具有某种版本控制方法(例如git)的文件夹中运行大规模破坏性命令,以防止不可逆转的损坏。 - Abandoned Cart以上方法在OSX上都不适用。
请按照以下步骤操作:
perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt
grep
和find
的答案在Mac上都完美地运行了(而且效率更高)。 - Abandoned Cart如果您正在使用zsh终端,您可以使用通配符魔法:
sed -i "" "s/search/high-replace/g" *.txt
一份可在Linux和Mac OS X上运行的版本(通过向sed
添加-e
开关):
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
export LC_CTYPE=C && export LANG=C
- cjoy2021
对我有效的方法:
LC_ALL=C && LANG=C && find . -type f | xargs sed -i '' 's/old/new/g'
LC_ALL=C && LANG=C &&
这部分,我就成功了。你为什么需要它呢? - Raphael Rafatpanah这是我在 Mac OS X 10.10.4 上可行的方案。
grep -e 'this' -rl . | xargs sed -i '' 's/this/that/g'
$ grep -e 'fastapi' -rl . | xargs sed -i '' 's/fastapi/flask/g'
,以下是输出结果:sed: RE error: illegal byte sequence
。 - uberrebuhttps://gist.github.com/nateflink/9056302
很好,因为现在我只需要打开终端,然后复制以下内容:
curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
有时会出现一些奇怪的字节序列错误,所以这里是完整的代码:
#!/bin/bash
#By Nate Flink
#Invoke on the terminal like this
#curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "replace-a-url.com"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: ./$0 [find string] [replace string]"
exit 1
fi
FIND=$1
REPLACE=$2
#needed for byte sequence error in ascii to utf conversion on OSX
export LC_CTYPE=C;
export LANG=C;
#sed -i "" is needed by the osx version of sed (instead of sed -i)
find . -type f -exec sed -i "" "s|${FIND}|${REPLACE}|g" {} +
exit 0
find . -type f -name '*.txt' -exec sed -i '' s/thistext/newtext/ {} +
g
,否则它只会替换一行中第一个出现的thistext
。所以你的正则表达式应该是s/thistext/newtext/g
。 - Les Nightingill
apple.stackexchange.com
,因为它既不够通用也不适用于所有开发人员。 - AlikElzin-kilaka