Mawk में स्क्रिप्ट का नाम कैसे प्रिंट करें?


13

बैश $0में स्क्रिप्ट का नाम होता है, लेकिन अगर मैं निम्नलिखित सामग्री के साथ myscript.awk नाम की स्क्रिप्ट बनाता हूं तो awk में:

#!/usr/bin/awk -f
BEGIN{ print ARGV[0] }

और इसे चलाएं, यह केवल "awk" प्रिंट करेगा। इसके अलावा, ARGV [i] i> 0 के साथ केवल कमांड लाइन में स्क्रिप्ट तर्क के लिए उपयोग किया जाता है। तो, इस मामले में "myscript.awk" स्क्रिप्ट का नाम कैसे प्रिंट करें?


मैंने शीर्षक को awk से mawk में बदल दिया है क्योंकि सभी समाधानों में gawk की आवश्यकता होती है और सामान्य awk के साथ काम नहीं करते हैं, और विशेष रूप से mawk के साथ जो कि व्यापक रूप से उपयोग किया जाता है (उदाहरण के लिए Ubuntu पर)
cipper

क्या आपको लगता mawkहै कि Ubuntu पर डिफ़ॉल्ट है? मेरे 15.04 वीएम पर, डिफ़ॉल्ट awkहै gawk। जबकि mawk स्थापित है यह डिफ़ॉल्ट नहीं है।
terdon

1
यदि आप इसे कहते हैं तो यह एक अजीब स्क्रिप्ट है awk -f myscript.awk। हालांकि, यह प्रश्न में समस्या से संबंधित नहीं है।
बजे

1
@EdMorton यह एक awkस्क्रिप्ट है क्योंकि यह इसके साथ शुरू होती है #!/usr/bin/awk -f। शेल स्क्रिप्ट की शुरुआत #!/bin/sh(या कुछ इसी तरह) से होती है।
बारमर

1
मैं विभिन्न शेल विशेषज्ञों से बात कर रहा हूं और इस बात पर एक निश्चित उत्तर पाने की कोशिश कर रहा हूं कि क्या यह शेल या awk स्क्रिप्ट है और आश्चर्यजनक रूप से # के साथ शुरू होने वाली फ़ाइलों की व्याख्या POSIX के अनुसार! अपरिभाषित है और इसका कोई विशेष प्रकार का नाम नहीं है। हालांकि कुछ लोग इसे शेल या ऑक स्क्रिप्ट के बजाय "हैश बैंग इंटरप्रेटर स्क्रिप्ट" के रूप में संदर्भित करते हैं, पर सर्वसम्मति से ऐसा लगता है कि इसे एक अर्क स्क्रिप्ट माना जाना चाहिए, भले ही कर्नेल (शेल) पहली पंक्ति की व्याख्या नहीं करता हो, लेकिन फिर भी उस पहली पंक्ति को भी पार्स करने में सक्षम होना चाहिए (एक टिप्पणी के रूप में) और आप इसका उपयोग करके निष्पादित कर सकते हैं awk -f file
एड मॉर्टन

जवाबों:


5

GNU के साथ सायगविन पर बैश में 4.1.3:

$ cat tst.sh
#!/bin/awk -f
BEGIN { print "Executing:", ENVIRON["_"] }

$ ./tst.sh
Executing: ./tst.sh

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

$ cat tst2.sh
awk -v cmd="$0" '
BEGIN { print "Executing:", cmd }
' "$@"

$ ./tst2.sh
Executing: ./tst2.sh

वह अंतिम किसी भी प्लेटफ़ॉर्म पर किसी भी शेल में किसी आधुनिक awk के साथ काम करेगा।


ध्यान दें कि पहले एक केवल बाश, zsh या ksh में काम करता है। बाद में शेल स्क्रिप्ट के बारे में है, जो स्क्रिप्ट नहीं है।
cuonglm

2
धन्यवाद! ENVIRON["_"]पूरी तरह से काम करता है, और यह किसी भी बाहरी कार्यक्रम को कॉल नहीं करता है। दूसरा विकल्प इस awk -v ...बात पर निर्भर करता है कि कोई स्क्रिप्ट कैसे चलाता है; मुझे यह नहीं चाहिए।
सिपाही

1
आपकी स्क्रिप्ट tst.shको कॉल करना भ्रामक है। यह एक awkस्क्रिप्ट है, शेल स्क्रिप्ट नहीं। BEGINएक मान्य शेल कमांड नहीं है।
बमर

1
लेकिन पोर्टेबिलिटी का सवाल यह नहीं है कि "ENVIRON है [] पोर्टेबल" यह " ENVIRON["_"]कॉलिंग शेल स्क्रिप्ट पथ का उत्पादन करता है जब हर awk से प्रत्येक शेल से शेलंग के माध्यम से कॉल किया जाता है"? मैं एक शेखबैंग से एक अजीब स्क्रिप्ट कभी नहीं कहूंगा कि मैं व्यक्तिगत रूप से जवाब के बारे में परवाह नहीं करता हूं, लेकिन मैंने सोचा था कि मैं इसका उल्लेख करूंगा .... ओह मैं ऊपर की टिप्पणियों में देखता हूं कि @cuonglm ने उत्तर दिया कि यह केवल कुछ गोले में समर्थित है। ।
एड मॉर्टन

1
अच्छी बात है, @ ई.डी. डैश में विफल होने के रूप में सत्यापित (जो मौजूदा एक के बजाय पिछले कमांड (या शेल खुद को) लौटाता है )। ksh93 दिलचस्प ढंग से पूर्वकाल में पीआईडी ​​को उपसर्ग करता है, जैसे *12345*/tmp/test.awkARGV[0]मज़बूती से हमेशा awkडैश, बैश, zsh और ksh93 में होता है।
एडम काट्ज

5

मुझे नहीं लगता कि यह gawk प्रलेखन के अनुसार संभव है :

अंत में, ARGV[0]आपके ऑपरेटिंग सिस्टम के आधार पर (सेक्शन 7.5 बिल्ट-इन वेरिएबल्स) का मान भिन्न होता है। कुछ प्रणालियाँ awkवहाँ रखी हैं, कुछ ने awk (जैसे /bin/awk) का पूरा पथनाम डाल दिया , और कुछ ने आपकी स्क्रिप्ट ('सलाह') का नाम रख दिया। अपना ARGV[0]स्क्रिप्ट नाम प्रदान करने के लिए मूल्य पर भरोसा न करें।

पर linuxआप एक गंदा हैक का एक प्रकार का उपयोग कर कोशिश कर सकते हैं और के रूप में द्वारा टिप्पणी में बताया स्टीफन Chazelas यह संभव है अगर के कार्यान्वयन awkका समर्थन करता है NUL बाइट्स:

#!/usr/bin/awk -f

BEGIN { getline t < "/proc/self/cmdline"; split(t, a, "\0"); print a[3]; }

लगता है आपकी स्क्रिप्ट काम नहीं कर रही है। यह सिर्फ "k" को प्रिंट करता है यदि "awk -f script.awk" के साथ कहा जाता है, और यह "s ./script.awk" द्वारा "s" प्रिंट करता है
cipper

@cipper: यहाँ यह साथ काम करता है gawkऔर विफल रहता है (आपके विवरण की तरह) mawk। दिलचस्प!

यह मेरे लिए लिनक्स में काम करता है, awk- 4.0.2। के साथ freebsd में /proc/curpoc/cmdline, और awkपरिणाम तुम्हारा जैसा है लेकिन साथ काम करता है gawk
तालीज़ीन

डिफ़ॉल्ट ubuntu पर यह काम नहीं करता है। पोर्टेबल समाधान खोजना अच्छा होगा।
16

1
@taliezin: क्यूंग्लम का उत्तर कोई समाधान नहीं है क्योंकि इसे अपने नाम के साथ स्क्रिप्ट को मैन्युअल रूप से फीड करना होगा। यह कॉलिंग की तरह है awk -vNAME="myscript.awk" ./myscript.awkऔर फिर स्क्रिप्ट के अंदर NAME प्रिंट करें। समाधान नहीं।
सिपाही c

5

मैं awk के भीतर से कमांड नाम प्राप्त करने का कोई सीधा तरीका नहीं जानता। आप इसे एक उप-शेल के माध्यम से प्राप्त कर सकते हैं।

gawk

GNU awk और psकमांड से आप PROCINFO["PID"]कमांड नाम को वर्कअराउंड के रूप में प्राप्त करने के लिए प्रोसेस आईडी का उपयोग कर सकते हैं । उदाहरण के लिए:

cmdname.awk

#!/usr/bin/gawk -f

BEGIN {
  ("ps -p " PROCINFO["pid"] " -o comm=") | getline CMDNAME
  print CMDNAME
}

mawk और nawk

आप एक ही दृष्टिकोण का उपयोग, लेकिन प्राप्त कर सकते हैं awkसे की पीआईडी $PPIDविशेष खोल चर (माता पिता की पीआईडी):

cmdname.awk

#!/usr/bin/mawk -f

BEGIN { 
  ("ps -p $PPID -o comm=") | getline CMDNAME
  print CMDNAME
}

परीक्षण

स्क्रिप्ट को इस तरह से चलाएं:

./cmdname.awk

दोनों मामलों में आउटपुट:

cmdname.awk

मुझे एक त्रुटि मिली: / bin / sh: 1: -o: नहीं मिली
cipper

@cipper: यह केवल GNU awk के साथ काम करता है, मैंने लापता शेबंग लाइन को जोड़ा।
थोर

से gawk मैनुअल : POSIX के अनुसार, 'अभिव्यक्ति | getline 'अस्पष्ट है अगर अभिव्यक्ति में' $ 'के अलावा अनपेक्षित संचालक शामिल हैं - उदाहरण के लिए, "" इको "" तिथि "| गेटलाइन 'अस्पष्ट है क्योंकि संघनन संचालक कोष्ठक नहीं है। आपको इसे "(" प्रतिध्वनि "" तिथि ") के रूप में लिखना चाहिए | getline 'अगर आप चाहते हैं कि आपका प्रोग्राम सभी awk कार्यान्वयन के लिए पोर्टेबल हो।
सिपाही

1
यह जरूरत है gawkकि यह एक है gawkएक के बजाय समाधान awkसमाधान। मुझे लगता है कि @cipper को प्रश्न के लिए अपनी इच्छा "पोर्टेबल समाधान" जोड़ना चाहिए।

1
@ थोर: क्यूंग्लम का जवाब एक समाधान नहीं है क्योंकि इसे अपने नाम के साथ स्क्रिप्ट को मैन्युअल रूप से फीड करना होगा। यह कॉलिंग की तरह है awk -vNAME="myscript.awk" ./myscript.awkऔर फिर स्क्रिप्ट के अंदर NAME प्रिंट करें। समाधान नहीं।
सिपाही c

4

POSIX के साथ awk:

#!/usr/bin/awk -f

BEGIN {
    print ENVIRON["AWKSCRIPT"]
}

फिर:

AWKSCRIPT=test.awk ./test.awk
test.awk

5
आप मैन्युअल रूप से इसमें स्क्रिप्ट का नाम फीड करते हैं, यह सेल्फ-प्रिंटिंग तरीका नहीं है
cipper

@ कैपर: ठीक है, यह सबसे आसान और पोर्टेबल तरीका है जिसकी मैं कल्पना कर सकता हूं।
congonglm

3
यह कॉलिंग की तरह है awk -vNAME="myscript.awk" ./myscript.awkऔर फिर NAMEस्क्रिप्ट के अंदर वेरिएबल को प्रिंट करें । समाधान नहीं।
सिपाही c

@ इस्परर: यदि आप उल्लेख करते हैं तो यह एकमात्र तरीका है mawk। और उपयोग ENVIRONकरना भी उपयोग करने के समान नहीं है -vNAME="myscript.awk", क्योंकि कब mawkसे एस्केप सीक्वेंस का विस्तार होगा NAME
cuonglm

4

GNU awk का उपयोग करना

जीएनयू जाग उपयोगकर्ता की मार्गदर्शिका की जाँच - 7.5.2 अंतर्निर्मित चर जो कॉनवे सूचना मैं पर ठोकर खाई:

PROCINFO #

इस सरणी के तत्व चल रहे awk प्रोग्राम के बारे में जानकारी तक पहुँच प्रदान करते हैं। निम्नलिखित तत्व (वर्णानुक्रम में सूचीबद्ध) उपलब्ध होने की गारंटी है:

PROCINFO [ "pid"]

वर्तमान प्रक्रिया की प्रक्रिया आईडी।

इसका मतलब है कि आप रनटाइम के दौरान प्रोग्राम के पीआईडी ​​को जान सकते हैं। फिर, system()इस दिए गए PID के साथ प्रक्रिया को देखने के लिए उपयोग करने की बात है :

#!/usr/bin/gawk -f
BEGIN{ pid=PROCINFO["pid"]
       system("ps -ef | awk '$2==" pid " {print $NF}'")
}

मैं उपयोग ps -efकरता हूं , जो 2 कॉलम पर पीआईडी ​​प्रदर्शित करता है। मान लें कि निष्पादक के माध्यम से किया जाता है awk -f <script>और कोई अन्य पैरामीटर नहीं है, हम मान सकते हैं कि पंक्ति के अंतिम क्षेत्र में वह जानकारी है जो हम चाहते हैं।

यदि हमारे पास कुछ पैरामीटर हैं, तो हमें लाइन को अलग-अलग पार्स करना होगा-बेहतर, psहम जिस कॉलम में रुचि रखते हैं , उसे प्रिंट करने के कुछ विकल्पों का उपयोग करें ।

परीक्षा

$ awk -f a.awk 
a.awk
$ cp a.awk hello.awk
$ awk -f hello.awk 
hello.awk

यह भी ध्यान दें कि GNU awk उपयोगकर्ता का एक और अध्याय बताता है कि ARGV जाने का रास्ता नहीं है:

1.1.4 निष्पादन योग्य कार्यक्रम

अंत में, आपके ऑपरेटिंग सिस्टम के आधार पर ARGV का मान [0] (बिल्ट-इन वेरिएबल्स) बदलता है। कुछ सिस्टम वहां 'awk' डालते हैं, कुछ ने awk (जैसे / बिन / awk) का पूरा पथनाम डाल दिया, और कुछ ने आपकी स्क्रिप्ट ('सलाह') का नाम डाल दिया। (dc) अपना स्क्रिप्ट नाम प्रदान करने के लिए ARGV [0] के मूल्य पर भरोसा न करें।


दुर्भाग्य से PROCINFO केवल एक gawk विशेषता है, सामान्य awk नहीं। उदाहरण के लिए यह
mawk

मुझे पता है ... आपने प्रश्न [gawk] के साथ क्यों टैग किया?
फेडोरक्वी

आप सही हे। जब मैंने प्रश्न पोस्ट किया तो मुझे mawk और gawk के बीच इन सभी अंतरों के बारे में पता नहीं था। टैग अब बदल कर mawk हो गया है।
सिपाही c

@cipper अच्छा:) मैं वास्तव में परीक्षण कर रहा था mawkऔर यह काम नहीं कर सका, ताकि मैं gawkअपने उबंटू में स्थापित हो जाऊं और यह काम कर सके। तो एक वर्कअराउंड का उपयोग किया जा सकता है gawk: D
fedorqui

1
@terdon, gawkUbuntu पर (या कम से कम कुछ Ubuntu संस्करण, जहां mawkडिफ़ॉल्ट awkकार्यान्वयन है) डिफ़ॉल्ट रूप से स्थापित नहीं है । IIRC, मुझे इसे डेबियन पर भी स्थापित करना था।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.