मैक और लिनक्स पर पाठ फ़ाइलों में पुनरावर्ती खोज और प्रतिस्थापित करें


127

लिनक्स शेल में, निम्न कमांड पुन: खोज करेगा और 'इस' के सभी उदाहरणों को 'उस' के साथ बदल देगा (मेरे सामने लिनक्स शेल नहीं है, लेकिन यह करना चाहिए)।

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

OSX पर एक समान कमांड क्या दिखेगा?


संभवत: apple.stackexchange.comइसे ले जाया जाना चाहिए क्योंकि यह न तो लिनक्स के लिए पर्याप्त है और न ही सभी देवों के लिए।
एलिकएल्ज़िन-किलाका

जवाबों:


246

ओएस एक्स बीएसडी और जीएनयू उपकरणों के मिश्रण का उपयोग करता है, इसलिए हमेशा सर्वश्रेष्ठ प्रलेखन की जांच करें (हालांकि मेरे पास ऐसा lessथा जो ओएस एक्स मैनपेज के अनुरूप नहीं था):

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

sed -iबैकअप के लिए एक्सटेंशन के बाद तर्क लेता है । -i ''बिना बैकअप के एक खाली स्ट्रिंग ( ) प्रदान करें ।

निम्नलिखित करना चाहिए:

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

-type fसिर्फ अच्छा अभ्यास है; यदि आप इसे एक निर्देशिका देते हैं तो sed शिकायत करेगा। -execअधिक पसंद किया जाता है xargs; आप के साथ -print0या कुछ भी परेशान नहीं की जरूरत है। {} +अंत का मतलब है कि कम से findके बजाय कहा जाता कमांड का एक उदाहरण के लिए तर्क के रूप में सभी परिणाम में संलग्न कर देगा, प्रत्येक परिणाम के लिए यह फिर से चल रहा है। (एक अपवाद है जब OS द्वारा अनुमत कमांड-लाइन तर्कों की अधिकतम संख्या का उल्लंघन किया जाता है, उस स्थिति में findकिसी भी उदाहरण से अधिक चलेगा।)


2
इस प्रतिस्थापन में मेरे "इस" में एक फॉरवर्ड स्लैश (लोकलहोस्ट / साइट) है - मैं एक .html फ़ाइल में एक URL के कुछ हिस्सों को प्रतिस्थापित कर रहा हूँ .... मैं इस तरह का प्रतिस्थापन कैसे करूँ। मैंने डबल-कोट्स में डालने की कोशिश की, लेकिन यह विफल रहा।
टिमोथी टी।

6
सैड सिंटैक्स स्लैश के स्थान पर लगभग किसी भी वर्ण का उपयोग करने की अनुमति देता है , जैसे आप %चरित्र का उपयोग कर सकते हैं sed "s%localhost/site%blah/blah%":। एक अन्य विकल्प बैकस्लैश-सेपरेटर से बचने के लिए है sed "s/localhost\/site/blah\/blah/":।
तैलानूब

धन्यवाद, मुझे वह कोशिश करने दो। हालांकि मैंने स्लैश को अलग करने के लिए {} का उपयोग करने की कोशिश की और मुझे अभी भी एक त्रुटि मिली ...
टिमोथी टी।

16
किसी और को illegal byte sequenceत्रुटि हो रही है? यदि ऐसा है, तो प्रयास करें: LC_ALL=C find . -type f -name '*.txt' -exec sed -i '' s/this/that/ {} +यह मेरे लिए काम किया।
कोल्डटुना

10
यह प्रति फ़ाइल केवल एक महासागर की जगह लेगा, /gकई LC_ALL=C find . -type f -exec sed -i '' s/search/replace/g {} +
महासागरों के

153

मैक के लिए, अधिक समान दृष्टिकोण यह होगा:

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

10
मैं चाहता हूं कि मैं हर बार इसे वापस लाऊं और इसका इस्तेमाल करूं। यह अब तक, आसान पर +15 होगा।
दरोगाओं

किसी कारण से, यह मेरे लिए काम नहीं करता है। यह कुछ नहीं करता है। मैं फ़ोल्डर form360 के अंदर हूँ और मैं सभी स्ट्रिंग इंस्टेंसेस को नाम बदलने के लिए आसान करने के लिए form360 में बदलने की कोशिश कर रहा हूँ, मैं निम्नलिखित कमांड चला रहा हूँ:find . -name '*.php' -print0 | xargs -0 sed -i "" "s/easyform/form360/g"
एंड्रेस रामोस

2
मेरे लिए, यह सही उत्तर होना चाहिए। यह केवल एक ही है जो मेरे लिए काम करता है।
nosequeldeebee 6

1
–प्रति ० | xargs -0 मेरे मैक पर काम नहीं करता है जब फ़ाइल नाम में स्थान होता है।
user2807219

1
sed:।: इन-प्लेस एडिटिंग केवल नियमित फाइलों के लिए काम करती है
कोडस्लैपर

14

वैकल्पिक समाधान के रूप में, मैं इसे मैक ओएसएक्स 10.7.5 पर उपयोग कर रहा हूं

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

इसका श्रेय जाता है: टोड सेसर के जवाब


यह एक अच्छी तरह से काम करता है! अन्य स्क्रिप्ट OSX पर कुछ मामलों में लाइन का एक अतिरिक्त छोर जोड़ती है! आपका बहुत बहुत धन्यवाद!
सेबस्टियन फाइल

14

मैक OSX 10.11.5 पर यह ठीक काम करता है:

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

xargs -I @ sed -i '' s / old-word / new-word / g '@ मेरे लिए काम करने के बाद इतने सारे गैर-कार्यशील सुझाव। धन्यवाद!
DrB

13

OSX पर उपरोक्त कार्य में से कोई भी नहीं।

निम्न कार्य करें:

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

1
अगर SEARCH_FOR और REPLACE_WITH रास्ते हैं तो '/' को कैसे स्कैन करें?
रैलवव

एक अलग परिसीमन का उपयोग करें। यदि आप पथ का उपयोग कर रहे हैं, तो एक बृहदान्त्र या पाइप काम करेगा। उदाहरण के लिए 'SEARCH | REPLACE | g'। 'S {SEARCH} {REPLACE}' के रूप में हमारे उपयोग ब्रेसिज़।
dannysauer

1
dito सवाल, यह मैक पर नहीं की कोशिश कर रहा है - लेकिन यह एक त्रुटि उत्पन्न करता है? उदाहरण के लिए, मेरा पथ एक फ़ाइल के रूप में व्याख्या किया गया है? -बैश: लोकलहोस्ट / नोस्टो: ऐसी कोई फ़ाइल या निर्देशिका नहीं
टिमोथी टी।

यह फ़ोल्डरों के माध्यम से गहरी पुनरावृत्ति नहीं करता है। केवल एक स्तर।
सर्गेई रोमानोव

इस आदेश के बारे में अधिक जानकारी के लिए यह पढ़ lifehacker.com/5810026/...
kuzdu

7

एक संस्करण जो लिनक्स और मैक ओएस एक्स दोनों पर काम करता है ( -eस्विच को जोड़कर sed):

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

मुझे इस जवाब से निर्यात करना पड़ा + स्वीकृत उत्तर से लाइन (मुझे बैकअप फ़ाइलों को उत्पन्न नहीं करना था)
लांस

2
'अवैध बाइट अनुक्रम' त्रुटि को export LC_CTYPE=C && export LANG=C
स्वीकार करने के लिए

यदि आप Git का उपयोग कर रहे हैं तो मैंने '* .filetype' के बजाय '*' के साथ इसे रन न करें। या आप अपने सभी अप्रकाशित कार्यों को अलविदा कह सकते हैं।
सर्गेई

1
Sed कमांड के मैक संस्करण को -i के बाद एक '' की आवश्यकता होती है, इसलिए यह उत्तर गलत है
G Huxley

2

जब भी मैं इस कमांड को टाइप करता हूं तो मुझे हमेशा यह नली लगती है, या झंडा भूल जाते हैं। मैंने तयलूब के जवाब के आधार पर जीथब पर एक जिस्ट बनाया जो वर्तमान निर्देशिका से एक वैश्विक खोज को प्रतिस्थापित करता है। यह मैक OSX विशिष्ट है।

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

यह अच्छा है क्योंकि अब मैं सिर्फ एक टर्मिनल खोलता हूँ, तो इसमें कॉपी करें:

कर्ल-एस https://gist.github.com/nateflink/9056302/raw/findreplaceosx.sh | bash -s "find-a-url.com" "प्रतिस्थापित-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

2

यह मेरा काम करने योग्य है। Mac OS X 10.10.4 पर

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

ऊपर वाले खोज का उपयोग उन फाइलों को बदल देंगे जिनमें खोज पाठ नहीं है (फ़ाइल अंत में एक नई पंक्ति जोड़ें), जो कि क्रिया है।


2

यदि आप एक zsh टर्मिनल का उपयोग कर रहे हैं तो आप वाइल्डकार्ड मैजिक का उपयोग करने में सक्षम हैं:

sed -i "" "s/search/high-replace/g" *.txt


1

मैंने इस प्रारूप का उपयोग किया - लेकिन ... मैंने पाया कि मुझे इसे वास्तव में हर उदाहरण को बदलने के लिए इसे तीन या अधिक बार चलाना था जो मुझे बहुत अजीब लगा। एक बार इसे चलाने से प्रत्येक फ़ाइल में कुछ बदल जाएगा लेकिन सभी नहीं। दो-चार बार एक ही स्ट्रिंग चलाने से सभी उदाहरणों को पकड़ा जा सकता है।

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

आपको इस कमांड को कई बार चलाने की जरूरत है b / c आपके sed regex gको अंत में जरूरत है , अन्यथा यह केवल thistextएक लाइन में पहली घटना को प्रतिस्थापित करता है । तो आपका रेगेक्स होना चाहिएs/thistext/newtext/g
लेस नाइटिंगिल

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


-3

OSX पर कमांड बिल्कुल वैसा ही होना चाहिए जैसा कि सुंदर UI के तहत यूनिक्स है।


मैंने जितना सोचा था, लेकिन नहीं। यह sed को फीड करते समय फाइलों के सामने एक ./ डालता है, इसलिए sed 'अवैध कमांड कोड' की शिकायत करता है। शायद मैं बस थक गया हूं ;-)
जैक

@JacobusR, कृपया अपने OSX टर्मिनल से कट और पेस्ट करें - आपको कुछ अलग दर्ज करना होगा।
ग्लेन जैकमैन

3
आप चाहते हैं कर सकते हैं -print0करने के लिए जोड़ा findझंडे और -0करने के लिए xargsझंडे।
jmtd

आप, साथ ही उपयोग कर सकते हैं -exec sed -i s/this/that/g {} \+के बजाय -printऔर xargs
मैरिएन

@JacobusR - यह काम करता है, भले ही एक अग्रणी './' पथनाम हो। हालाँकि, यदि फ़ाइल नाम में कोई स्थान है, तो "./jacobus \ R.txt" कहें, का उपयोग xargsहो सकता है कि अंतरिक्ष-सीमांकित "./jacobus" को पास करने के लिए एक फ़ाइल के रूप में देखें sed, और फिर "R.txt" के साथ। , जिनमें से कोई भी मौजूद नहीं है।
ब्रेट हेल

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.