Cd के लिए पथ के रूप में grep आउटपुट का उपयोग कैसे करें?


9

मैं कमांड के grepतर्क के रूप में आउटपुट कैसे कर सकता हूं cd?

उदाहरण के लिए:

[root@xxx xxx]# pip install django | grep '/usr.*'  
Requirement already satisfied (use --upgrade to upgrade): django in   /usr/lib64/python2.7/site-packages

यहां /usr/lib64/python2.7/site-packagesहाइलाइट किया गया है और मैं इस स्ट्रिंग को पास करना चाहता हूं cd

जवाबों:


16

बैश के कमांड प्रतिस्थापन का उपयोग करें $(), आपको -oकेवल मिलान वाले हिस्से का चयन करने के लिए grep की भी आवश्यकता है :

cd "$(pip install django | grep -o '/usr.*')"

ध्यान दें कि हालांकि आप इस मामले में दूर हो जाएंगे, लेकिन आपको हमेशा कमांड प्रतिस्थापन को दोहरे उद्धरणों के साथ संलग्न करना चाहिए ताकि शेल व्हाट्सएप पर शब्द विभाजन का प्रदर्शन न करे (डिफ़ॉल्ट स्थान, टैब और न्यूलाइन द्वारा, IFSमामले में चर पर निर्भर करता है bash)।


9

आप जो करते हैं उसके आधार पर और पहले से नहीं जानते कि क्या है pip उत्पादन होगा , आप grepइसके अलावा कुछ के लिए फैसला कर सकते हैं /usr.*

यदि आप जानते हैं कि निर्देशिका के साथ शुरू होता है/usr (और यह उत्पादन की रेखा के अंत में दिखाई देता है pip, और यह कि /usrनिर्देशिका नाम से पहले लाइन पर कहीं भी प्रकट नहीं होता है), तो यह एक अच्छा विकल्प है;heemayl का जवाब आपको बताता है कि कैसे।

यदि आपको पता है कि इसका कारण यह /usrहै कि आप कमांड को केवल चलाते हैं और जिस निर्देशिका को आप बदलना चाहते हैं, उसे जानते हैं, तो मैं कमांड चलाने का सरल उपाय बताता हूं cd /usr/lib64/python2.7/site-packages। यदि आप टैब पूर्णता का उपयोग नहीं करते हैं तो भी यह कम टाइपिंग है ।

अन्यथा, आप आउटपुट के पार्स होने के बारे में जो जानते हैं, उसके आधार पर आप एक अलग रीजेक्सप चुन सकते हैं। नीचे दिए गए सभी विकल्प अभी भी मान लेते हैं कि निर्देशिका नाम पंक्ति के अंत में दिखाई देता है, लेकिन अन्य धारणाएं बदलती हैं।

यदि आपको पता है कि निर्देशिका का नाम निरपेक्ष है (यानी, से शुरू होता है /) और /निर्देशिका नाम से पहले लाइन पर नहीं दिखाई देता है , तो आप उसी रीगेक्सप का उपयोग कर सकते हैं जैसे हेमायल के उत्तर में लेकिन /इसके बजाय /usr:

cd "$(pip install django | grep -o '/.*')"

यह किसी भी वर्ण के /शून्य या अधिक ( *) के बाद मेल खाता है (. )।

यदि आप जानते हैं कि निर्देशिका नाम में कोई क्षैतिज व्हाट्सएप (कोई स्थान या टैब नहीं है) और पंक्ति के अंत में दिखाई देता है , तो आप निम्न कार्य कर सकते हैं:

cd "$(pip install django | grep -oP '[^\h]+$')"

यहाँ मैंने एक पर्ल रेगेक्सपी ( -P) का उपयोग किया है क्योंकि \hसंक्षिप्त नाम (के लिए [:blank:]) टाइप करने के लिए और एक बराबर विस्तारित रेगेक्सपी ( -E) की तुलना में पढ़ना आसान बनाता है । यह +वर्णों के वर्ग में किसी भी वर्ण के एक या अधिक ( ) से मेल खाता है ( [ ]) जो नहीं है ( ^) एक स्थान या टैब ( \h)।

अगर आपको पता है कि वह निर्देशिका नाम तुरंत inक्षैतिज व्हाट्सएप से घिरा हुआ है (यानी, रिक्त स्थान पर बाईं और दाईं ओर दोनों को गद्देदार), और यह कि लाइन पर एकमात्र ऐसी घटना हैin , तो आप इसका उपयोग कर सकते हैं:

cd "$(pip install django | grep -oP '\hin\h+\K.+')"

यह \Kएक या अधिक वर्ण ( .+) जो एक स्थान या टैब ( \h) के बाद दिखाई देते हैं in, और एक और एक या एक से अधिक रिक्त स्थान या टैब ( \h+), वास्तव में शामिल inऔर रिक्त स्थान के बिना मेल करने के लिए शून्य-चौड़ाई पॉजिटिव लुक-पीछे अभिकथन ( ) का उपयोग करता है मैच में इसे घेर लें। लुक-अराउंड अस्लीमेंट्स पर्ल रेगुलर एक्सप्रेशंस की एक विशेषता है।

पैटर्न ने भी काम किया होगा, लेकिन हमें केवल एक खाली देखने की जरूरत है , चाहे कितने भी मौजूद हों। इसके विपरीत, हमें बाद में सभी ब्लैंक से मेल खाना चाहिए , या वे द्वारा त्याग नहीं किया जाएगा और उन्हें निर्देशिका नाम के भाग के रूप में मिलान किया जाएगा।\h+in\h+\K.+inin\K

यदि आपको पता है कि निर्देशिका का नाम पंक्ति की अंतिम घटना के तुरंत inबाद आता है , तो क्षैतिज व्हाट्सएप द्वारा उपयोग किया जा सकता है:

set +H
cd "$(pip install django | grep -oP '\hin\h+(?!.*\hin\h.*)\K.*')"
set -H

वहाँ, शून्य-चौड़ाई पॉजिटिव लुक-बैक ऐसर्ज़ेशन में स्वयं एक शून्य-चौड़ाई नकारात्मक लुक-फॉरवर्ड अभिकथन ( (?! )) शामिल है।

इस तरह से !प्रकट होता है जैसे कि सुरुचिपूर्ण ढंग से बचना मुश्किल है ; जिस विधि का उपयोग मैंने इसे शेल इतिहास विस्तार को ट्रिगर करने से रोकने के लिए किया है, उसे कमांड को चलाने से पहले grepअस्थायी रूप से इतिहास विस्तार ( set +H) को अक्षम करने के लिए और set -Hबाद में इसे फिर से सक्षम करने के लिए किया जाता है । यदि आप इसका उपयोग किसी स्क्रिप्ट में कर रहे हैं और आपकी स्क्रिप्ट में यह शामिल नहीं है set -H, तो आपको ऐसा करने की आवश्यकता नहीं है क्योंकि इतिहास विस्तार स्वचालित रूप से तभी सक्षम होता है जब कोई शेल इंटरेक्टिव रूप से चलता है।

अंत में, ध्यान दें कि इनमें से कोई भी, और न ही heemayl का जवाब है, वास्तव में के उत्पादन पाइप कर रहे हैं grepकरने के लिए cd(हालांकि के उत्पादन में pipअभी भी करने के लिए पहुंचाया जा रहा है grep)। पाइपों के बजाय , इस काम के लिए उपयुक्त उपकरण कमांड प्रतिस्थापन है


बेशक, यदि आप तकनीकी प्राप्त करना चाहते हैं , तो शेल कमांड आउटपुट को पढ़ने के लिए आंतरिक रूप से एक पाइप का उपयोग करता है।
रैंडम 832

@ Random832 अच्छा बिंदु - मैंने इस पर विचार करते हुए थोड़ा संपादन किया है। Btw, क्या आप जानते हैं कि क्या कमांड प्रतिस्थापन में "हुड के नीचे" पाइप का उपयोग किया जा सकता है? या यह एक कार्यान्वयन विवरण है जो संभावित रूप से बैश के एक अलग, भविष्य के संस्करण में अलग तरीके से किया जा सकता है? (बेशक, व्यवहार में, मैं समझता हूं कि यह इसे करने का सबसे अच्छा तरीका है, और इस तरह इसे अलग तरीके से लागू किए जाने की संभावना नहीं है।)
एलियाह कगन

1
नहीं, इसकी गारंटी नहीं है, सिद्धांत रूप में एक शेल एक नामित फीफो या टेम्प फाइल का उपयोग कर सकता है, हालांकि इसका कोई कारण नहीं है।
रैंडम 832

क्या आप इतिहास विस्तार के बारे में निश्चित हैं? केवल वर्ण जो इसे ब्लॉक कर सकते हैं वे ` and `` हैं, और आपके पास grep अभिव्यक्ति के चारों ओर एकल उद्धरण का उपयोग है।
मूरू

1
@ ममरू हां, इसका विस्तार है। मैंने या तो ध्यान नहीं दिया था, लेकिन जब मैंने इसका परीक्षण किया तो पता चला। !साथ वहाँ उद्धृत नहीं किया गया है ', के रूप में -quotes '-quotes खुद को उद्धृत कर रहे हैं। कमांड की जटिलता इसके प्रभाव की गलत भविष्यवाणी करना आसान बनाती है, लेकिन जाहिर तौर पर विस्तार के क्रम के कारण ( !यह जल्दी है) यह काम करना शुरू कर देता है जैसे x=foo; echo "'$x'"(-> 'foo')। बाहरी "-क्वॉट्स को हटाने से -क्वॉट किया जाएगा और इतिहास के विस्तार को रोका !जा 'सकेगा, लेकिन cd अगर निर्देशिका के नाम पर व्हाट्सएप है तो यह विफल हो जाएगा।
एलियाह कगन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.