2012-03-14 47 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