कैट कमांड और इको


14

मैं एक फ़ाइल की सामग्री के साथ प्रतिध्वनि से आउटपुट को बदलना चाहूंगा। मैंने निम्नलिखित कॉमैंड की कोशिश की है:

echo "abc" | cat 1.txt > 2.txt

लेकिन 2.txtफ़ाइल में केवल सामग्री शामिल है 1.txt। यह काम क्यों नहीं करता है?


3
प्रोग्राम catकेवल मानक इनपुट से पढ़ते हैं यदि उनके पास कोई फ़ाइल नाम तर्क नहीं है।
बरमार

जवाबों:


23

यह काम नहीं करता है क्योंकि catआपके पाइप अनुक्रम में echoप्रोग्राम को मानक इनपुट से प्रोग्राम के आउटपुट को पढ़ने का निर्देश नहीं दिया गया था ।

आप -मानक इनपुट को इंगित करने के लिए एक छद्म फ़ाइल नाम के रूप में उपयोग कर सकते हैं cat। से man catएक msys2 स्थापना पर:

EXAMPLES
       cat f - g
              Output f's contents, then standard input, then g's contents.

इसलिए कोशिश करें

echo "abc" | cat - 1.txt > 2.txt

बजाय।


21

जैसा कि दूसरों ने नोट किया है, आपका मूल आदेश विफल हो गया है क्योंकि cat 1.txtइसके मानक इनपुट की उपेक्षा है। या तो इंगित करें कि यह इसका पहला तर्क होना चाहिए ( cat - 1.txt), या ब्लॉक पुनर्निर्देशन का उपयोग पुनर्निर्देशित करना echo abc और cat 1.txt एक साथ करना। अर्थात:

{ echo abc; cat 1.txt; } > 2.txt 

मैनुअल से प्रासंगिक अंश ( man bash):

यौगिक कमांड
एक यौगिक कमांड निम्नलिखित में से एक है। ज्यादातर मामलों में एक कमांड के विवरण में एक सूची को एक या अधिक नई सुर्खियों द्वारा शेष कमांड से अलग किया जा सकता है, और इसके बाद अर्धविराम के स्थान पर एक नई पंक्ति हो सकती है।

(सूची)

    सूची को एक सबहेल्ड वातावरण में निष्पादित किया जाता है (नीचे COMMAND EXECUTION ENVIRONMENT देखें)। वैरिएबल असाइनमेंट और बिल्डिन कमांड जो शेल के वातावरण को प्रभावित करते हैं कमांड के पूरा होने के बाद प्रभाव में नहीं रहते हैं। वापसी की स्थिति सूची की निकास स्थिति है।

{सूची; }

    सूची को केवल वर्तमान शेल वातावरण में निष्पादित किया जाता है।  सूची को एक नई पंक्ति या अर्धविराम के साथ समाप्त किया जाना चाहिए। इसे एक ग्रुप कमांड के रूप में जाना जाता है । वापसी की स्थिति सूची की निकास स्थिति है । ध्यान दें कि अक्षरों से परे विपरीत (और ), {और }कर रहे हैं आरक्षित शब्द और होने चाहिए जहां एक आरक्षित शब्द मान्यता प्राप्त किया जा करने की अनुमति है। चूंकि वे एक शब्द विराम का कारण नहीं बनते हैं, उन्हें सूची से व्हॉट्सएप या किसी अन्य शेल मेटाचैकर द्वारा अलग किया जाना चाहिए ।

पहला विकल्प (उपधारा वातावरण) में साइड इफेक्ट्स का एक गुच्छा होता है, सबसे अधिक अगर सभी आपके परिदृश्य के लिए अप्रासंगिक नहीं हैं; हालाँकि, यदि कमांड के आउटपुट का एक गुच्छा पुनर्निर्देशित किया जाता है, तो आपको जरूरत है, तो विकल्प # 2 यहाँ (समूह कमांड) पसंद किया जाता है।


7
( echo "abc"; cat 1.txt ) > 2.txt

आपने बिल्ली को इको आउटपुट दिया, लेकिन इनपुट के लिए बिल्ली का कोई उपयोग नहीं था, और इसे अनदेखा कर दिया। अब कमांड एक के बाद एक चलती हैं, और उनका आउटपुट समूहीकृत (कोष्ठक) और 2.txt में निर्देशित होता है।


1
यह उत्तर यह बताकर सुधारा जा सकता है कि यह कैसे काम करता है और ओपी का मूल प्रयास क्यों काम नहीं करता है।
बॉब

ठीक है, यह एक कोशिश दी।
गेरार्ड एच। पिल

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

आह, लेकिन मैं कभी भी बैश का उपयोग नहीं करता।
जेरार्ड एच। पिल

1
@ GerardH.Pille: जबकि डैनियल के जवाब से उद्धरण है bash(1), यह व्यवहार का वर्णन करता है कि हर POSIX- अनुरूप शेल का समर्थन करना चाहिए।
जी-मैन का कहना है कि 'मोनिका'

2

आपकी कमांड cat 1.txtआउटपुट के साथ कुछ नहीं करती है echo "abc"

इसके बजाय: (echo "abc"; cat 1.txt) > 2.txt दोनों कमांड के आउटपुट को 2.txt में लिखेंगे।


सुझाए गए वैकल्पिक कार्यों के बारे में बताकर इस उत्तर को बेहतर बनाया जा सकता है।
बॉब

1

किसी भी POSIX शेल में आप cat fileइनपुट के रूप में उपयोग करने के लिए कमांड प्रतिस्थापन का उपयोग कर सकते हैं echo:

echo $(cat file1.txt) "This Too"

बैश में आप प्रक्रिया प्रतिस्थापन का उपयोग कर सकते हैं और एक और "फ़ाइल" के catरूप में इको का उपयोग कर सकते हैं , जैसे कि:

cat file1.txt <(echo This Too)

और फिर पाइप या आउटपुट को पुनर्निर्देशित करें जैसा कि आप फिट देखते हैं।

हर दूसरे जवाब की तरह, बिल्ली नज़रअंदाज़ करती है अगर उसे देखने के लिए एक फ़ाइल मिल गई है। (मुझे डैनियल और mvw के उत्तर भी पसंद हैं, उनके लिए +1)


1
ओपी का मूल प्रयास काम नहीं करता (और इसलिए इसके बजाय यह आवश्यक क्यों है) यह समझाकर इस उत्तर को बेहतर बनाया जा सकता है।
बॉब

1
<(command)निर्माण एक बैश विस्तार है। यह POSIX नहीं है, इसलिए आप उन लिपियों पर भरोसा नहीं कर सकते हैं जिन्हें माना जाता है /bin/sh
रिआल्टो

0

बस एक अनुमान है, लेकिन ऐसा लगता है कि आपके पास एक दोहराने योग्य प्रक्रिया है, जो एक उपनाम या फ़ंक्शन के लिए एक अच्छा उम्मीदवार है। उपनाम आमतौर पर बैश कमांड को लागू करने के लिए शॉर्ट कट होते हैं, जैसे कि संक्षिप्त नाम, इसके इनपुट / तर्क के रूप में एकल इनपुट स्ट्रीम पर।

alias hg="history | grep"

हालाँकि, इस मामले में, एक फ़ंक्शन अधिक पठनीय होगा, क्योंकि आप कई, असतत (2) इनपुट धाराओं के साथ-साथ कई बैश कमांड का संयोजन कर रहे हैं। आपके पास दो तर्क हैं, पहला एक स्ट्रिंग और दूसरा एक फ़ाइलपथ। अंत में, आप चाहते हैं कि परिणाम stdout आउटपुट स्ट्रीम पर लिखा जाए।

CLI प्रॉम्प्ट से, यह टाइप करें:

# ecat()        
{
echo ${1}
cat ${2}
}

आपके फंक्शन का नाम ecat है, जो यादगार है।

अब आप के रूप में आमंत्रित कर सकते हैं

ecat "abc" 1.txt

संलग्न करने के लिए, बस स्टडआउट के लिए एक अलग आउटपुट गंतव्य की आपूर्ति करें:

ecat "abc" 1.txt >> 2.txt

परिशिष्ट पुनर्निर्देशन ऑपरेटर '>>' आउटपुट को निर्दिष्ट फ़ाइल के अंत में जोड़ देगा।

यदि आप इसे पसंद करते हैं, तो पुन: उपयोग के लिए अपनी ~ / .bashrc फ़ाइल में जोड़ें।

declare -f ecat >> ~/.bashrc

इसका मतलब यह भी है कि आप अपने फ़ंक्शन की परिभाषा के भीतर, आदि को सजा सकते हैं।

फ़ाइलों को अपने ~ / .bashrc में जोड़कर अधिलेखित होने से बचाने के लिए भी एक अच्छा विचार है

set noclobber

2
अपने कार्य को ठीक से व्यवहार करने के लिए, आपको उपयोग करना चाहिए "$1"और "$2"। इस संदर्भ में, घुंघराले ब्रेसिज़ कोई अच्छा नहीं करते हैं। देखें ${name}मतलब यह नहीं है कि आप क्या सोचते यह होता है ...
जी-मैन का कहना है कि 'मोनिका'

1
noclobberसुझाव को प्रश्न के अनुकूल कैसे बताया जा सकता है ? (मैं इस बात से भी बहुत ज्यादा सहमत नहीं हूँ कि यह अच्छी सलाह है - वैश्विक व्यवहार को संशोधित करना स्क्रिप्ट / सलाह / व्यवहार को ध्यान में रखकर बनाया गया है)।
चार्ल्स डफी

0

निम्नलिखित कोड भी काम करेगा:

echo abc >> 1.txt && cat 1.txt > 2.txt

इको एबीसी के आउटपुट को 1.txt के साथ जोड़ा जाएगा >> इसके बाद && इसे कमांड के अगले सेट को चलाने के लिए कहेगा जो 1.txt को कैट करेगा और फिर इसे 2.txt पर आउटपुट करेगा । असल में, यह पहले कमांड के आउटपुट को 1.txt में जोड़ता है और फिर 1.txt के आउटपुट को 2.txt में भेजता है।

यदि आप चाहते हैं कि एबीसी पहले दिखाई दे, तो आप निम्नलिखित कोड का उपयोग कर सकते हैं:

echo abc >> 2.txt && cat 1.txt >> 2.txt

1
यह इच्छा (1) डाल abcपर नीचे की 2.txt; सवाल यह शीर्ष पर चाहता है। (2)  फ़ाइल को संशोधित करें 1.txt; यह अस्वीकार्य है।
जी-मैन का कहना है कि 'मोनिका'

ऐसा कहां कहा गया है? Ringger81 ने कभी नहीं निर्दिष्ट किया कि 2.txt में वह कहाँ प्रदर्शित होना चाहता था। आप उन चीजों को मान रहे हैं जो प्रश्न कभी नहीं बताता है।
नासिर रिले

(1) ठीक है, आप # 1 पर एक वैध बिंदु बढ़ाते हैं। यद्यपि प्रश्न में "फ़ाइल से सामग्री" से पहले "इको से आउटपुट" का उल्लेख किया गया है, और फिर नमूना कमांड में echoपहले रखा गया catहै, मुझे लगता है कि यह कभी नहीं, स्पष्ट रूप से , यह कहता है कि यह इको से पहले आउटपुट चाहता है। इनपुट फ़ाइल की सामग्री। ऐसा लगता है कि ज्यादातर लोगों ने इसकी व्याख्या इस तरह से की। (2)  1.txtएक इनपुट फ़ाइल है। सवाल संशोधन के बारे में कुछ नहीं कहता है 1.txt। तथ्य यह है कि इनपुट फ़ाइलों को संशोधित नहीं किया जाना चाहिए बिना कहे चला जाता है।
जी-मैन का कहना है कि 'मोनिका'

मैं आपकी बात को समझ सकता हूं कि अशुद्ध फाइल को संशोधित नहीं करना है। मेरा दूसरा कोड ऐसा किए बिना वांछित प्रभाव को प्राप्त करेगा।
नासिर रिले

1
एक फ़ाइल खोलना, उसे जोड़ना, उसे बंद करना , उसे फिर से खोलना, फिर से अपील करना ... ऐसा क्यों है कि बजाय इसे केवल एक बार खोलें और दोनों परिचालनों के लिए पुनर्निर्देशन को रखें?
चार्ल्स डफी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.