मैक पर -i विकल्प विफल होने के साथ sed कमांड, लेकिन लिनक्स पर काम करता है


303

मैंने निम्नलिखित का सफलतापूर्वक उपयोग किया है sed लिनक्स में टेक्स्ट को खोजने / बदलने के लिए कमांड का :

sed -i 's/old_link/new_link/g' *

हालाँकि, जब मैं इसे अपने मैक ओएस एक्स पर आज़माता हूँ, मुझे मिलता है:

"कमांड सी एक्सपेक्ट्स \ _ पाठ के बाद"

मुझे लगा कि मेरा मैक एक सामान्य बीएचएस शेल चलाता है। क्या हो रहा है?

संपादित करें:

@ उच्च प्रदर्शन के अनुसार, यह मैक sedएक अलग (बीएसडी) स्वाद के कारण है, इसलिए मेरा सवाल यह होगा कि मैं बीएसडी में इस कमांड को कैसे दोहराऊं sed?

संपादित करें:

यहाँ एक वास्तविक उदाहरण है जो इसका कारण बनता है:

sed -i 's/hello/gbye/g' *

1
इसका मतलब है कि sedआपके डेटा में कमांड के रूप में "c" दिखता है। क्या आप एक चर का उपयोग कर रहे हैं? कृपया कुछ ऐसा पोस्ट करें जो वास्तविक कमांड का प्रतिनिधित्व करता है और कुछ डेटा जो आप प्रोसेस कर रहे हैं। आप इस त्रुटि का एक सरल प्रदर्शन कर सकते हैं echo x | sed c
अगली सूचना तक रोक दिया गया।

@ डेनिस, ऊपर दिया गया साधारण कमांड इसका कारण बनता है, हालाँकि यह जो डाटा प्रोसेसिंग कर रहा है वह एक पूरी वेबसाइट है (मैं सभी इमेज लिंक को परिवर्तित कर रहा हूं), जिसमें html और css फाइलें भी शामिल हैं ...
यारिन

जवाबों:


397

यदि आप उपयोग करते हैं -i विकल्प का आपको अपने बैकअप के लिए एक्सटेंशन प्रदान करने की आवश्यकता होती है।

यदि आपके पास है:

File1.txt
File2.cfg

आदेश (ध्यान दें के बीच स्थान की कमी -iऔर ''और -eयह मैक की और GNU पर नए संस्करण पर काम करने के लिए):

sed -i'.original' -e 's/old_link/new_link/g' *

2 बैकअप फाइल बनाएं जैसे:

File1.txt.original
File2.cfg.original

बैकअप फ़ाइलों को बनाने से बचने के लिए कोई पोर्टेबल तरीका नहीं है क्योंकि सभी मामलों पर काम करने वाली sed कमांड्स का मिश्रण खोजना असंभव है:

  • sed -i -e ...- OS X पर काम नहीं करता क्योंकि यह -eबैकअप बनाता है
  • sed -i'' -e ... - OS X 10.6 पर काम नहीं करता बल्कि 10.9+ पर काम करता है
  • sed -i '' -e ... - जीएनयू पर काम नहीं

ध्यान दें कि सभी प्लेटफार्मों पर काम करने वाली एक सीड कमांड नहीं है, आप उसी परिणाम को प्राप्त करने के लिए किसी अन्य कमांड का उपयोग करने का प्रयास कर सकते हैं।

उदाहरण के लिए, perl -i -pe's/old_link/new_link/g' *


4
मेरी भी यही समस्या थी। इस समाधान के लिए धन्यवाद। लेकिन जहाँ मैंने sed -आई ’का वर्णन खोजने के लिए sed मैन सेड’ के साथ कोशिश की, वहाँ बैकअप का अनदेखा करने के लिए -i ’का उपयोग करने के बारे में कुछ भी नहीं है। यह मेरा पहला दोष है। दूसरा, जब त्रुटि "कमांड की उम्मीद है कि पाठ के बाद \" दिखाई देती है, तो यह सीधे हमें क्यों नहीं बताता है कि यह विकल्प '-i' के लिए एक बैकअप नाम की उम्मीद करता है !! " इस तरह की बात हर जगह होती है: आपको एक त्रुटि मिलती है लेकिन त्रुटि क्यों नहीं होती है, तो आप उस मैनुअल को खोजते हैं जो इसके बारे में कुछ नहीं बताता है। फिर आप इसे किसी और को ढूंढने के लिए भी गूगल करें यही समस्या है। मेरा मतलब है, मैनुअल में उदाहरण क्यों नहीं दे रहे हैं?
lukmac

या हमें बताएं कि केवल सूचना-संदेश के बजाय त्रुटि क्यों होती है जो त्रुटि होती है। यह सभी उपकरण निर्माताओं के लिए एक सुझाव है, अगर वे कभी भी इस टिप्पणी को पढ़ सकते हैं।
lukmac

5
@lukmac जहाँ तक sedबता सकते हैं, आप एक बैकअप प्रत्यय की आपूर्ति करते हैं। बैकअप प्रत्यय है s/old_link/new_link/g। उसके बाद अगला तर्क एडिटिंग कमांड्स का होना चाहिए। क्योंकि इसने कमांड को बैकअप नाम के रूप में व्याख्यायित किया, इसने एडिटिंग कमांड्स के रूप में पहला फ़ाइल नाम लिया, लेकिन वे मान्य नहीं थे।
बमर

2
क्या यह हमेशा एक मुद्दा होगा? क्या कोई ऐसा तरीका है जिससे Apple OSX के साथ वर्कअराउंड / पैकेज GNU सेड बनाने में सक्षम हो सकता है? या, GNU sed समर्थन नहीं कर सका sed -i '' -e ...?
17

5
sed -i'' -eके रूप में काम करने की उम्मीद नहीं लगती है MAC 10.14
MoOx

64

जब आप मैं का उपयोग बैकअप फ़ाइलों के लिए एक विस्तार है मैं ओएस एक्स पर विश्वास करते हैं की आवश्यकता । प्रयत्न:

sed -i .bak 's/hello/gbye/g' *

GNU का उपयोग करना sedविस्तार वैकल्पिक है


55

यह GNU और BSD दोनों सेड के संस्करणों के साथ काम करता है:

sed -i'' -e 's/old_link/new_link/g' *

या बैकअप के साथ:

sed -i'.bak' -e 's/old_link/new_link/g' *

-iविकल्प के बाद लापता स्थान पर ध्यान दें ! (GNU sed के लिए आवश्यक)


7
पहले एक पर OSX काम (मैं सिर्फ 10.6.8 पर यह परीक्षण किया है) नहीं है
मार्सिन

4
ओएस एक्स (10.10.3) पर मेरे लिए, पहले-निर्मित बैकअप फ़ाइलों को -e के साथ प्रत्यय दिया गया था। अच्छा नहीं। दूसरा केवल वही चीज थी जो मेरे लिए उबंटू और ओएस एक्स के बीच लगातार काम करती थी। मैं बैकअप फाइलें नहीं चाहता था, इसलिए मुझे rmइसे हटाने के लिए एक कमांड चलाना पड़ा ।
ब्रेंडन

1
पहली पंक्ति को 10.10: sed -i'' ...=> पर काम करने के लिए एक जगह के साथ फिर से लिखा जाना चाहिए sed -i '' ...
डैनियल जोम्पे

3
@DanielJomphe लेकिन इस जगह को जोड़ने पर GNU sed
Brice

1
@marcin पहले एक मेरे लिए और साथ ही OSX 10.11.2 पर काम करता है। केवल एक चीज यह है कि यह एक बैकअप फ़ाइल बनाता है, जिसे बाद में हटाने की आवश्यकता होती है। दूसरा बेहतर दिखता है, क्योंकि हमें बाद में फ़ाइल नाम का पता नहीं लगाना है।
vikas027

41

मैक में एक ही समस्या थी और इसे हल किया brew:

brew install gnu-sed

और के रूप में उपयोग करें

gsed SED_COMMAND

आप (जैसे चाहें) sedउर्फ के रूप में सेट कर सकते gsedहैं:

alias sed=gsed

3
क्यों आप वास्तव में दिया एक ही जवाब के रूप में ओहद Kravchick ?
gniourf_gniourf

1
इस तरह से अन्य लोगों को स्थापित करना एक महान विचार नहीं है
सांताएक्सएल

1
एक उपनाम के बजाय, इसी काढ़ा पृष्ठ में अनुशंसित के रूप में, इसे पथ में जोड़ें: पथ = "$ (काढ़ा - उपसर्ग) / ऑप्ट / ग्नू-सेड / लिबेनेक्स / ग्नुबिन: $ पैथ"
यूलिसिस

24

या, आप अपने मैक में जीएनयू संस्करण के सीड को संस्थापित कर सकते हैं, जिसे गेस्ड कहा जाता है, और मानक लिनक्स सिंटैक्स का उपयोग करके इसका उपयोग कर सकते हैं।

उसके लिए, gsedबंदरगाहों का उपयोग करके स्थापित करें (यदि आपके पास नहीं है, तो इसे http://www.macports.org/ पर प्राप्त करें ) sudo port install gsed। फिर, आप चला सकते हैंsed -i 's/old_link/new_link/g' *


24
.. या यदि आप होमब्रे का उपयोग करते हैं, तो स्थापित करेंgnu-sed
सुडर

1
धन्यवाद @ सुदर, डबल-थम्स अप!
एंड्रयू स्वैन

9

आपका मैक वास्तव में एक BASH शेल चलाता है, लेकिन यह अधिक सवाल है कि आप किस सेड का कार्यान्वयन कर रहे हैं। मैक सीड पर बीएसडी से आता है और आमतौर पर एक विशिष्ट लिनक्स बॉक्स पर आपको मिलने वाले सेड से अलग होता है। मैं आपको सुझाव देता हूं man sed


3
बीएसडी मुद्दे की ओर इशारा करने के लिए धन्यवाद- लेकिन मैं काफी अनपढ़ हूँ और मुझे अपने आदेश के लिए एक त्वरित सुधार की आवश्यकता
यारिन

5
@ यारिन - नहीं, और अगर मैं आदमी सेड पर एक त्वरित नज़र रखता हूं, तो यह आपको कुछ भी नहीं बताता है। एक लंबी झलक आज़माएं।
उच्च प्रदर्शन मार्क

21
ज्यादातर एसओ जवाब एक आदमी में कहीं दफन कर रहे हैं, लेकिन यह है कि एसओ के लिए है - व्यस्त लोग हैं, जो स्मार्ट लोगों से जवाब की जरूरत है
यारिन

9

Sinetris का उत्तर सही है, लेकिन मैं इसे findकमांड के साथ उपयोग करता हूं कि मैं किन फाइलों को बदलना चाहता हूं। सामान्य तौर पर यह काम करना चाहिए (ओएक्सएक्स पर परीक्षण किया गया /bin/bash):

find . -name "*.smth" -exec sed -i '' 's/text1/text2/g' {} \;

सामान्य तौर पर जब जटिल परियोजनाओं में sedबिना उपयोग findकरना कम कुशल होता है।


-execबहुत अच्छा है! मैं बस सोच रहा था कि क्या अंत में स्लैश वास्तव में ज़रूरत है
ये लियू

2
@YeLiu: बिना \, ;जब मुझे इस तरह की कोशिश की गई तो शेल द्वारा व्याख्या की गई
सेव-इन

2

मैंने sedMacOS (MacOS 10.12 पर परीक्षण) और अन्य OS के बीच अंतर को संभालने के लिए एक फ़ंक्शन बनाया है :

OS=`uname`
# $(replace_in_file pattern file)
function replace_in_file() {
    if [ "$OS" = 'Darwin' ]; then
        # for MacOS
        sed -i '' -e "$1" "$2"
    else
        # for Linux and Windows
        sed -i'' -e "$1" "$2"
    fi
}

उपयोग:

$(replace_in_file 's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' "./mysql/.env")

कहाँ पे:

, एक परिधि है

's,MASTER_HOST.*,MASTER_HOST='"$MASTER_IP"',' पैटर्न है

"./mysql/.env" फ़ाइल करने के लिए पथ है


1

यहां टेम्प्लेट फ़ाइल (कोई बैकअप की आवश्यकता) के लिए पर्यावरण चर को लागू करने का तरीका बताया गया है।

1. बाद में बदलने के लिए {{FOO}} के साथ टेम्पलेट बनाएं।

echo "Hello {{FOO}}" > foo.conf.tmpl

2. Foo चर और आउटपुट के साथ {{FOO}} को नई foo.conf फ़ाइल में बदलें

FOO="world" && sed -e "s/{{FOO}}/$FOO/g" foo.conf.tmpl > foo.conf

दोनों macOS 10.12.4 और Ubuntu 14.04.5 दोनों पर काम कर रहा है


0

जैसा कि अन्य उत्तर इंगित करते हैं, बैकअप फाइल बनाने के बिना ओएस एक्स और लिनक्स में सीमांत रूप से उपयोग करने का कोई तरीका नहीं है। इसलिए, मैंने इसके बजाय ऐसा करने के लिए इस रूबी वन-लाइनर का उपयोग किया:

ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml

मेरे मामले में, मुझे इसे एक rakeकार्य (यानी एक रूबी स्क्रिप्ट के अंदर) से कॉल करने की आवश्यकता थी , इसलिए मैंने इस अतिरिक्त स्तर के उद्धरण का उपयोग किया:

sh %q{ruby -pi -e "sub(/ $/, '')" ./config/locales/*.yml}

-1
sed -ie 's/old_link/new_link/g' *

बीएसडी और लिनक्स दोनों पर काम करता है


3
यह लिंक्ड के साथ एक और फ़ाइल नाम पर बनाता eहै
Brice

1
टूटी, इसे हटाने के लिए बेहतर है।
सोरिन

यह मैक और लिनक्स पर काम कर रहा है। इस समाधान के साथ क्या समस्या है?
इस्लाम अजाब

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