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

时间:2023-01-07 16:48:27

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上类似的命令是什么样子的?

11 个解决方案

#1


175  

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

OS X使用BSD和GNU工具的混合,所以最好总是检查文档(尽管我有更少的甚至不符合OS X手册):

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

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

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

sed将-i后的参数作为备份的扩展。为没有备份提供一个空字符串(-i”)。

The following should do:

下面应该做的是:

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

找到。型f - name”*。txt' -exec sed -i ' s/this/that/ {} +

The -type f is just good practice; sed will complain if you give it a directory or so. -exec is preferred over xargs; you needn't bother with -print0 or anything. The {} + at the end means that find will 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 find will run more than one instance.)

-type f是很好的练习;如果您给它一个目录,sed将会抱怨。-exec优先于xargs;不需要麻烦-print0之类的。在末尾的{}+,意味着find将把所有结果作为参数添加到被调用的命令的一个实例中,而不是为每个结果重新运行它。(一个例外是操作系统允许的命令行参数的最大数量被破坏;在这种情况下,find将运行多个实例。

#2


97  

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

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

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

#3


10  

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

归功于:托德·塞西尔的回答

#4


9  

On Mac OSX 10.11.5 this works fine:

在Mac OSX 10.11.5中,这样做很好:

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

#5


7  

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

一个适用于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'

#6


6  

None of the above work on OSX.

以上这些都不能用于OSX。

Do the following:

执行以下操作:

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

#7


0  

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上的一个基本原则,它从当前目录中进行全局查找替换。这是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- 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 "$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

#8


0  

https://bitbucket.org/masonicboom/serp is 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上测试,它对给定目录中的文件中的文本进行递归搜索和替换,并确认每个替换。它是新的,所以可能有bug。

Usage looks like:

使用看起来像:

$ 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

#9


0  

This is my workable one. on mac OS X 10.10.4

这是我能用的。mac OS X 10.10.4

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

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

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

#10


-3  

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

OSX上的命令应该与漂亮UI下的Unix完全相同。

#11


-3  

could just say $PWD instead of "."

只能说$PWD而不是"。"

#1


175  

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

OS X使用BSD和GNU工具的混合,所以最好总是检查文档(尽管我有更少的甚至不符合OS X手册):

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

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

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

sed将-i后的参数作为备份的扩展。为没有备份提供一个空字符串(-i”)。

The following should do:

下面应该做的是:

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

找到。型f - name”*。txt' -exec sed -i ' s/this/that/ {} +

The -type f is just good practice; sed will complain if you give it a directory or so. -exec is preferred over xargs; you needn't bother with -print0 or anything. The {} + at the end means that find will 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 find will run more than one instance.)

-type f是很好的练习;如果您给它一个目录,sed将会抱怨。-exec优先于xargs;不需要麻烦-print0之类的。在末尾的{}+,意味着find将把所有结果作为参数添加到被调用的命令的一个实例中,而不是为每个结果重新运行它。(一个例外是操作系统允许的命令行参数的最大数量被破坏;在这种情况下,find将运行多个实例。

#2


97  

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

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

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

#3


10  

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

归功于:托德·塞西尔的回答

#4


9  

On Mac OSX 10.11.5 this works fine:

在Mac OSX 10.11.5中,这样做很好:

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

#5


7  

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

一个适用于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'

#6


6  

None of the above work on OSX.

以上这些都不能用于OSX。

Do the following:

执行以下操作:

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

#7


0  

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上的一个基本原则,它从当前目录中进行全局查找替换。这是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- 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 "$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

#8


0  

https://bitbucket.org/masonicboom/serp is 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上测试,它对给定目录中的文件中的文本进行递归搜索和替换,并确认每个替换。它是新的,所以可能有bug。

Usage looks like:

使用看起来像:

$ 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

#9


0  

This is my workable one. on mac OS X 10.10.4

这是我能用的。mac OS X 10.10.4

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

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

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

#10


-3  

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

OSX上的命令应该与漂亮UI下的Unix完全相同。

#11


-3  

could just say $PWD instead of "."

只能说$PWD而不是"。"