awk 'processing_script_here' my=file.txt
अनिश्चित काल तक रुकना और प्रतीक्षा करना लगता है ... यहां
क्या हो रहा है और मैं इसे कैसे काम करूं?
awk 'processing_script_here' my=file.txt
अनिश्चित काल तक रुकना और प्रतीक्षा करना लगता है ... यहां
क्या हो रहा है और मैं इसे कैसे काम करूं?
जवाबों:
जैसा कि क्रिस कहते हैं , इनपुट फ़ाइल नामों के बजाय variablename=anything
(नए ( -v var=value
जो BEGIN
) कथन से पहले किए गए हैं ) के विपरीत , फॉर्म के तर्कों को चर असाइनमेंट के रूप में माना जाता है (उस समय जो तर्कों को संसाधित किया जाता है )।
यह इस तरह की चीजों में उपयोगी हो सकता है:
awk '{print $1}' FS=/ RS='\n' file1 FS='\n' RS= file2
जहाँ आप एक अलग FS
/ RS
प्रति फ़ाइल निर्दिष्ट कर सकते हैं । यह आमतौर पर भी उपयोग किया जाता है:
awk '!file1_processed{a[$0]; next}; {...}' file1 file1_processed=1 file2
इसका एक सुरक्षित संस्करण है:
awk 'NR==FNR{a[$0]; next}; {...}' file1 file2
(जो file1
खाली है तो काम नहीं करता है)
लेकिन यह उस तरह से हो जाता है जब आपके पास फाइलें होती हैं जिनके नाम में =
अक्षर होते हैं।
अब, यह केवल एक समस्या है जब पहली बार छोड़ दिया गया =
एक वैध awk
चर नाम है।
में एक वैध चर नाम का गठन awk
किसकी तुलना में कठोर है sh
।
POSIX के लिए कुछ ऐसा होना आवश्यक है:
[_a-zA-Z][_a-zA-Z0-9]*
पोर्टेबल चरित्र सेट के केवल पात्रों के साथ। हालांकि, /usr/xpg4/bin/awk
सोलारिस 11 कम से कम उस संबंध में आज्ञाकारी नहीं है और किसी भी वर्णक्रम के वर्णों को केवल नाम के ही नहीं, बल्कि चर नामों में स्थानिक नाम से अनुमति देता है।
तो जैसे एक तर्क x+y=foo
या =bar
या ./foo=bar
अभी भी कोई इनपुट फ़ाइल नाम और नहीं एक काम के रूप में व्यवहार किया जाता है के रूप में क्या बचा है की पहले =
एक वैध चर नाम नहीं है। कार्यान्वयन और स्थान के Stéphane=Chazelas.txt
आधार पर एक तर्क जैसा हो सकता है या नहीं awk
।
यही कारण है कि awk के साथ, इसका उपयोग करने की अनुशंसा की जाती है:
awk '...' ./*.txt
के बजाय
awk '...' *.txt
उदाहरण के लिए समस्या से बचने के लिए यदि आप txt
फ़ाइलों के नाम की गारंटी नहीं दे सकते हैं तो इसमें =
अक्षर नहीं होंगे ।
इसके अलावा, सावधान रहें कि -vfoo=bar.txt
यदि आप उपयोग करते हैं तो एक तर्क को एक विकल्प के रूप में माना जा सकता है:
awk -f file.awk -vfoo=bar.txt
(यह भी लागू होता है awk '{code}' -vfoo=bar.txt
के साथ awk
बिजीबॉक्स संस्करणों से 1.28.0 करने से पहले, देखें बग रिपोर्ट इसी )।
फिर, इसके ./*.txt
चारों ओर काम का उपयोग करना (एक ./
उपसर्ग का उपयोग करना भी एक फ़ाइल के साथ मदद करता है जिसे बुलाया जाता है -
अन्यथा अन्यथा मानक इनपुट केawk
रूप में समझा जाता है )।
इसीलिए भी
#! /usr/bin/awk -f
शेबंग वास्तव में काम नहीं करते हैं। जबकि मानों को एक कथन में मानों var=value
को ठीक करके ARGV
(किसी ./
उपसर्ग को जोड़कर ) काम किया जा सकता है BEGIN
:
#! /usr/bin/awk -f
BEGIN {
for (i = 1; i < ARGC; i++)
if (ARGV[i] ~ /^[_[:alpha:]][_[:alnum:]]*=/)
ARGV[i] = "./" ARGV[i]
}
# rest of awk script
यह उन लोगों के विकल्प के साथ मदद नहीं करेगा जैसा कि उन लोगों द्वारा देखा जाता है awk
और awk
स्क्रिप्ट नहीं ।
उस ./
उपसर्ग का उपयोग करने के साथ एक संभावित कॉस्मेटिक मुद्दा यह समाप्त हो गया है FILENAME
, लेकिन substr(FILENAME, 3)
यदि आप नहीं चाहते हैं तो आप इसे हमेशा पट्टी करने के लिए उपयोग कर सकते हैं ।
जीएनयू कार्यान्वयन awk
उन सभी मुद्दों को इसके -E
विकल्प के साथ ठीक करता है ।
के बाद -E
, gawk केवल awk
स्क्रिप्ट के पथ (जहां -
अभी भी स्टडिन का मतलब है) की उम्मीद करता है और फिर केवल इनपुट फ़ाइल पथों की एक सूची (और वहां, -
विशेष रूप से इलाज भी नहीं किया जाता है)।
इसके लिए विशेष रूप से डिज़ाइन किया गया है:
#! /usr/bin/gawk -E
शेबबैंग्स जहां तर्कों की सूची हमेशा इनपुट फाइलें होती है (ध्यान दें कि आप अभी भी उस कथन ARGV
में उस सूची को संपादित करने के लिए स्वतंत्र हैं BEGIN
)।
आप इसका उपयोग इस रूप में भी कर सकते हैं:
gawk -e '...awk code here...' -E /dev/null *.txt
हम -E
खाली स्क्रिप्ट के साथ उपयोग करते हैं ( /dev/null
) बस यह सुनिश्चित करने के लिए कि *.txt
बाद में उन्हें हमेशा इनपुट फ़ाइलों के रूप में माना जाता है, भले ही वे =
वर्ण हों।
../foo
, /path/to/foo
और एक अलग एन्कोडिंग में मौजूद पथ हैं) - जिस स्थिति substr(FILENAME,3)
में यह पर्याप्त नहीं होगा, या यह नहीं है एक एक शॉट स्क्रिप्ट जहां उपयोगकर्ता मूल रूप से जानता है क्या फ़ाइल नाम हैं - जो मामले में / वह शायद उनमें से किसी से युक्त के साथ परेशान नहीं करना चाहिए =
या तो ;-)
./
यह एक समस्या है, लेकिन यह कहा जाता है कि यह कुछ शर्तों के तहत अवांछनीय हो सकता है, जैसे कि ऐसे मामले जिनमें फ़ाइल नाम को आउटपुट में शामिल किया ./
जाना है , जिसमें मामला अनावश्यक और अनावश्यक होना चाहिए, इसलिए आप 'किसी तरह इससे छुटकारा पाना होगा। यहाँ कम से कम एक उदाहरण है । जैसा कि उपयोगकर्ता जानते हैं कि फ़ाइल नाम क्या हैं - ठीक है, इस मामले में हम यह भी जानते हैं कि फ़ाइल नाम क्या है, लेकिन =
अभी भी उचित प्रसंस्करण के रास्ते में है। तो अग्रणी -
रास्ते में मिल सकता है ।
./
उस awk
(गलत) विशेषता के आसपास काम करने के लिए उपसर्ग का उपयोग करना चाहते हैं लेकिन फिर आप ./
आउटपुट पर उस के साथ समाप्त होते हैं जिसे आप पट्टी करना चाहते हैं। देखें कि कैसे जांच करें कि फ़ाइल की पहली पंक्ति में एक विशिष्ट स्ट्रिंग है? उदहारण के लिए।
./
बल्कि वैश्विक (निरपेक्ष पथ) भी है /
जो एक फ़ाइल के रूप में तर्क की व्याख्या करता है।
जाग के अधिकांश संस्करणों में, प्रोग्राम को निष्पादित करने के लिए तर्क या तो हैं:
x=y
चूँकि आपके फ़ाइलनाम की व्याख्या केस # 2 के रूप में की जा रही है, awk अभी भी स्टडिन पर कुछ पढ़ने के लिए प्रतीक्षा कर रहा है (क्योंकि यह अनुभव नहीं करता है कि कोई फ़ाइल नाम पारित किया गया है)।
संभवतः, यह व्यवहार POSIX में प्रलेखित है :
निम्नलिखित में से दो प्रकार के तर्क आपस में जुड़े हो सकते हैं:
- फ़ाइल: एक फ़ाइल का एक पथनाम जिसमें पढ़ने के लिए इनपुट होता है, जिसे प्रोग्राम में पैटर्न के सेट के साथ मिलान किया जाता है। यदि कोई फ़ाइल ऑपरेटर निर्दिष्ट नहीं है, या यदि कोई फ़ाइल ऑपरेंड '-' है, तो मानक इनपुट का उपयोग किया जाएगा।
- असाइनमेंट: एक ऑपरेंड जो पोर्टेबल कैरेक्टर सेट से अंडरस्कोर या अल्फाबेटिक कैरेक्टर से शुरू होता है (टेबल को IEEE Std 1003.1-2001, सेक्शन 6.1, पोर्टेबल कैरेक्टर सेट के बेस डेफिनेशन वॉल्यूम में देखें), इसके बाद अंडरस्कोर, डिजिट का एक सिक्वेंस आता है। और पोर्टेबल वर्ण सेट से वर्णमाला, उसके बाद '=' वर्ण, एक मार्गनाम के बजाय एक चर असाइनमेंट निर्दिष्ट करेगा।
जैसे कि, सुस्पष्ट रूप से, आपके पास कुछ विकल्प हैं (# 1 संभवतः कम से कम घुसपैठ है):
awk ... ./my=file
, जो इस के बाद .
से "पोर्टेबल चरित्र सेट से एक अंडरस्कोर या अक्षर चरित्र" नहीं है।awk ... < my=file
। हालाँकि, यह कई फ़ाइलों के साथ अच्छी तरह से काम नहीं करता है।ln my=file my_file
, और फिर my_file
सामान्य रूप से उपयोग कर सकते हैं । कोई भी नकल नहीं की जाएगी, और दोनों फ़ाइलों को एक ही डेटा और इनकोड मेटाडेटा द्वारा समर्थित किया जाएगा। इसका उपयोग करने के बाद, लिंक को हटाने के लिए सुरक्षित है क्योंकि इनोड के संदर्भों की संख्या अभी भी 0 से अधिक होगी।./my=file
काम नहीं करता है? % awk 'processing_script_here' ./my=file.txt awk: fatal: cannot open file ./my=file.txt' for reading (No such file or directory).
यह पोर्टेबल होना चाहिए क्योंकि ./my
एक मान्य चर नाम नहीं है, इसलिए इस तरह से पार्स नहीं किया जाना चाहिए।
=
पहले पोर्टेबल चरित्र सेट से एक अंडरस्कोर या अल्फाबेटिक चरित्र से पहले होता है (IEEE Std 1003.1-2001, धारा 6.1, पोर्टेबल चरित्र सेट के बेस डेफिनेशन वॉल्यूम में तालिका देखें), पोर्टेबल वर्ण सेट से अंडरस्कोर, अंक और वर्णमाला के अनुक्रम के बाद । इसलिए की तरह एक फ़ाइल पथ ++foo=bar.txt
या =foo
या ./foo=bar
सब ठीक हैं के रूप में है कि .
या +
एक नहीं है [_a-zA-Z]
।
./my=file
वर्बेटिम के माध्यम से पारित किया जाएगा।
awk '{print $1,$2}' /etc/passwd
। मुद्दा यह है कि शेल को खोलने के लिए फ़ाइल को खोलने के विपरीत जागने से कोई फर्क नहीं पड़ता है क्योंकि यह इसे खोजने योग्य बनाता है या नहीं। वास्तव में awk '{exit}' < /etc/passwd
, आप यह सुनिश्चित करने awk
के लिए पहले रिकॉर्ड के अंत में वापस जाने की अपेक्षा करेंगे exit
कि यह सुनिश्चित करने के लिए कि यह स्टड के भीतर स्थिति को छोड़ देता है। POSIX की आवश्यकता है कि /usr/xpg4/bin/awk
Solaris पर करता है, लेकिन GNU / Linux पर न तो ऐसा लगता है gawk
और न ही mawk
ऐसा लगता है।
awk
।
गॉक डॉक्युमेंटेशन को उद्धृत करने के लिए (नोट जोर जोड़ा):
कमांड लाइन पर किसी भी अतिरिक्त तर्क को सामान्यतः निर्दिष्ट आदेश में संसाधित की जाने वाली इनपुट फ़ाइलों के रूप में माना जाता है। हालाँकि, एक तर्क जिसके पास var var = value है, वैरिएबल var के मान को असाइन करता है - यह किसी फ़ाइल को निर्दिष्ट नहीं करता है।
आज्ञा रुककर इंतजार क्यों करती है? क्योंकि प्रपत्र में उपरोक्त परिभाषा द्वारा awk 'processing_script_here' my=file.txt
निर्दिष्ट कोई फ़ाइल नहीं है - my=file.txt
चर असाइनमेंट के रूप में व्याख्या की गई है, और यदि कोई फ़ाइल परिभाषित नहीं है, तो awk
स्टडिन (यह भी स्पष्ट है strace
कि यह दर्शाता है कि इस तरह के कमांड में awk read(0,'...)
syscall पर प्रतीक्षा कर रहा है ।
यह भी POSIX awk विनिर्देशों में प्रलेखित है , OPERANDS अनुभाग और उस के कार्य भाग देखें )
वैरिएबल असाइनमेंट awk '{print foo}' foo=bar /etc/passwd
उस मूल्य के रूप में स्पष्ट है जो foo
प्रत्येक पंक्ति के लिए / etc / passwd में मुद्रित होता है। निर्दिष्ट ./foo=bar
या पूर्ण पथ हालांकि काम करता है।
ध्यान दें कि चल strace
पर awk '1' foo=bar
और साथ ही साथ की जाँच cat foo=bar
से पता चलता है कि इस awk विशेष मुद्दा है, और के रूप में तर्क पारित कर दिया execve शो फ़ाइल नाम करता है, तो गोले इस मामले में env चर असाइनमेंट से कोई संबंध नहीं है।
इसके अतिरिक्त, कृपया ध्यान दें कि awk '...script...' foo=bar
शेल द्वारा पर्यावरण चर सृजन नहीं होगा, क्योंकि पर्यावरण चर असाइनमेंट को प्रभावी होने के लिए एक कमांड से पहले होना चाहिए। POSIX शैल व्याकरण नियम देखें , अंक संख्या 7. इसके अतिरिक्त इसके माध्यम से सत्यापित किया जा सकता हैawk '{print ENVIRON["foo"]}' foo=bar /etc/passwd