2012-03-14 126 views
78

在linux shell中,以下命令将递归搜索并用'that'替换'this'的所有实例(我的前面没有Linux shell ,但它应该这样做)。在Mac和Linux的文本文件中进行递归搜索和替换

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

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

+0

或许应该移至'apple.stackexchange.com'因为它不是一般的足够的Linux和所有开发者。 – 2016-07-14 05:42:40

回答

156

OS X使用的BSD和GNU工具的混合,所以最好经常检查文件(虽然我有它less甚至不符合OS X手册页):

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

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

下应该做的:

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

-type f就是很好的做法;如果你给它一个目录,sed会抱怨。 -exec优于xargs;你不需要打扰-print0或任何东西。 末尾的{} +表示find会将所有结果作为参数附加到被调用命令的一个实例,而不是为每个结果重新运行它。 (一个例外是OS允许的最大数量的命令行参数被破坏;在这种情况下,find将运行多个实例。)

+2

作品像一个魅力,谢谢,并欢迎来到stackoverflow ;-) – Jack 2012-03-15 07:33:09

+0

在这个替代我的“这个”包含一个正斜杠(本地主机/网站) - 我用.html文件替换URL的部分....我如何做这样的替代。我尝试了双引号,但失败了。 – Angela 2013-09-18 04:00:34

+3

Sed语法允许使用几乎*任何*字符代替斜杠,例如你可以使用'%'字符:'sed's%localhost/site%blah/blah%“'。另一种选择是反斜杠 - 转义分隔符:'sed“s/localhost \/site/blah \/blah /”'。 – TaylanUB 2013-09-18 11:06:06

-3

OSX上的命令应该和它在美观的UI下的命令完全一样。

+0

我以为很多,但没有。当喂入sed时它会在文件前面放一个./,所以sed会抱怨'无效的命令代码'。也许我只是累了;-) – Jack 2012-03-14 14:43:42

+0

@JacobusR,请从您的OSX终端剪切和粘贴 - 您必须输入稍有不同的内容。 – 2012-03-14 15:02:53

+2

您可能希望将'-print0'添加到'find'标志并将'-0'添加到'xargs'标志。 – jmtd 2012-03-14 16:46:50

-3

可能只是说$ PWD而不是“。”。

6

以上都不适用于OSX。

执行以下操作:

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

如果SEARCH_FOR和REPLACE_WITH是路径,如何查看'/'? – rraallvv 2013-03-29 16:35:16

+0

使用不同的分隔符。如果你正在使用路径,冒号或管道将起作用。例如,'| SEARCH | REPLACE | g'。我们使用大括号,如在'{SEARCH} {REPLACE}'中。 – dannysauer 2013-09-06 01:04:21

+1

dito问题,试图在Mac上没有 - 但它似乎产生一个错误?例如,我的路径被解释为一个文件? -bash:localhost/nohost:没有这样的文件或目录 – Angela 2013-09-18 04:02:30

90

在Mac上更加类似的做法是这样的:

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

我希望每次回到它并使用它时,我都可以使用它。到现在为止,这将是+15,很容易。 – Droogans 2015-02-26 15:35:05

+0

同意。这是唯一为我工作的人。 – 2016-08-11 09:00:30

+0

出于某种原因,它不适合我。它什么也没做。我在文件夹form360中,我试图将名称为easyform的所有字符串实例更改为form360,我正在运行以下命令:'find。 -name'* .php'-print0 | xargs -0 sed -i“”“s/easyform/form360/g”' – 2017-01-26 21:23:42

0

每当我输入这个命令时,我似乎总是把它堵上,或者忘掉一面旗帜。我根据TaylanUB的答案在github上创建了一个Gist,它从当前目录执行全局查找替换。这是Mac OSX特有的。

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

,因为现在我只弹出打开一个终端,然后在复制很高兴:

卷曲-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 
7

是在Linux和Mac OS X的工作(通过添加-e开关sed)一个版本:

export LC_CTYPE=C LANG=C 
find . -name '*.txt' -print0 | xargs -0 sed -i -e 's/this/that/g' 
+0

我必须从这个答案中输出+从接受的答案中输出的行(我不想要生成备份文件) – Lance 2014-04-29 19:46:40

+5

sed:RE错误:非法字节序列 – FelikZ 2014-12-28 15:31:12

+1

以解决'非法字节序列'错误,尝试在运行命令之前设置LOCALE: 'export LC_CTYPE = C && export LANG = C' – cjoy 2016-01-06 01:24:24

0

https://bitbucket.org/masonicboom/serp是走实用程序(即跨平台),在OSX测试,做递归搜索和替换为给定目录内的文件中的文本,并确认各替代品,它是新的,所以可能是越野车

用法是这样的:

$ 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 
-1

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

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

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

8

在Mac OSX 10.11.5这工作得很好:

grep -rli 'old-word' * | xargs [email protected] sed -i '' 's/old-word/new-word/g' @ 
+0

xargs -I @ sed -i''s/old-word/new-word/g'@在尝试了许多其他非工作建议后为我工作。谢谢! – BeC 2016-12-28 10:57:54