在 Mac 和 Linux 上的文本文件中递归搜索和替换

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9704020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:11:02  来源:igfitidea点击:

Recursive search and replace in text files on Mac and Linux

linuxmacosshell

提问by Hyman

In the linux shell, the following command will recursively search and replace all instances of 'this' with 'that' (I don't have a Linux shell in front of me, but it should do).

在 linux shell 中,以下命令将递归搜索所有 'this' 实例并将其替换为 'that'(我面前没有 Linux shell,但它应该这样做)。

find . -name "*.txt" -print | xargs sed -i 's/this/that/g'

What will a similar command on OSX look like?

OSX 上的类似命令会是什么样子?

采纳答案by TaylanUB

OS X uses a mix of BSD and GNU tools, so best always check the documentation (although I had it that lessdidn't even conform to the OS X manpage):

OS X 混合使用 BSD 和 GNU 工具,因此最好始终检查文档(尽管我的文档less甚至不符合 OS X 手册页):

https://web.archive.org/web/20170808213955/https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html

https://web.archive.org/web/20170808213955/https://developer.apple.com/legacy/library/documentation/Darwin/Reference/ManPages/man1/sed.1.html

sed takes the argument after -ias the extension for backups. Provide an empty string (-i '') for no backups.

sed 将参数 after-i作为备份的扩展名。-i ''为无备份提供空字符串 ( )。

The following should do:

以下应该做:

LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +

LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +

The -type fis just good practice; sed will complain if you give it a directory or so. -execis preferred over xargs; you needn't bother with -print0or anything. The {} +at the end means that findwill append all results as arguments to one instance of the called command, instead of re-running it for each result. (One exception is when the maximal number of command-line arguments allowed by the OS is breached; in that case findwill run more than one instance.)

-type f只是好的做法;如果你给它一个目录左右,sed 会抱怨。 -exec优先于xargs; 你不需要打扰-print0或任何事情。将{} +在年底意味着find将所有结果作为参数添加的,而不是给被叫命令的一个实例,再运行它为每个结果。(一个例外是当操作系统允许的最大命令行参数被违反时;在这种情况下find将运行多个实例。)

回答by clops

The command on OSX should be exactly the same as it is Unix under the pretty UI.

OSX 上的命令应该和 Unix 下漂亮的 UI 完全一样。

回答by Samuel Devlin

could just say $PWD instead of "."

可以只说 $PWD 而不是 "."

回答by eb80

None of the above work on OSX.

以上都不适用于 OSX。

Do the following:

请执行下列操作:

perl -pi -w -e 's/SEARCH_FOR/REPLACE_WITH/g;' *.txt

回答by Will

For the mac, a more similar approach would be this:

对于 mac,更类似的方法是:

find . -name '*.txt' -print0 | xargs -0 sed -i "" "s/form/forms/g"

回答by Maciej Gurban

As an alternative solution, I'm using this one on Mac OSX 10.7.5

作为替代解决方案,我在 Mac OSX 10.7.5 上使用这个

grep -ilr 'old-word' * | xargs -I@ sed -i '' 's/old-word/new-word/g' @

Credit goes to: Todd Cesere's answer

归功于Todd Cesere 的回答

回答by Nate Flink

Whenever I type this command I always seem to hose it up, or forget a flag. I created a Gist on github based off of TaylanUB's answer that does a global find replace from the current directory. This is Mac OSX specific.

每当我输入这个命令时,我似乎总是把它灌输,或者忘记一个标志。我根据 TaylanUB 的回答在 github 上创建了一个 Gist,它从当前目录中进行全局查找替换。这是 Mac OSX 特有的。

https://gist.github.com/nateflink/9056302

https://gist.github.com/nateflink/9056302

It's nice because now I just pop open a terminal then copy in:

这很好,因为现在我只是打开一个终端然后复制:

curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh| bash -s "find-a-url.com" "replace-a-url.com"

curl -s https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh| bash -s "find-a-url.com" "replace-a-url.com"

You can get some weird byte sequence errors, so here is the full code:

你可能会得到一些奇怪的字节序列错误,所以这里是完整的代码:

#!/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 "" ] || [ -z "" ]; then
  echo "Usage: ./
export LC_CTYPE=C LANG=C
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g'
[find string] [replace string]" exit 1 fi FIND= REPLACE= #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

回答by vroc

A version that works on both Linux and Mac OS X (by adding the -eswitch to sed):

适用于 Linux 和 Mac OS X 的版本(通过将-e开关添加到sed):

$ ls test
a  d  d2 z
$ cat test/z
hi
$ ./serp --root test --search hi --replace bye --pattern "*"                         
test/z: replace hi with bye? (y/[n]) y
$ cat test/z
bye

回答by user4425237

https://bitbucket.org/masonicboom/serpis a go utility (i.e. cross-platform), tested on OSX, that does recursive search-and-replace for text in files within a given directory, and confirms each replacement. It's new, so might be buggy.

https://bitbucket.org/masonicboom/serp是一个 go 实用程序(即跨平台),在 OSX 上测试,它对给定目录中的文件中的文本进行递归搜索和替换,并确认每次替换。这是新的,所以可能有问题。

Usage looks like:

用法如下:

grep -e 'this' -rl . | xargs sed -i '' 's/this/that/g'

回答by NoteCode

This is my workable one. on mac OS X 10.10.4

这是我的一个可行的。在 Mac OS X 10.10.4 上

##代码##

The above ones use findwill change the files that do not contain the search text (add a new line at the file end), which is verbose.

上面的使用find会改变不包含搜索文本的文件(在文件末尾添加一个新行),这是冗长的。