AWK के अंदर बैश शेल फंक्शन का उपयोग करना


24

क्या AWK के अंदर बाश फ़ंक्शन का उपयोग करना संभव है?

उदाहरण फ़ाइल (स्ट्रिंग, इंट, इंट, इंट)

Mike 247808 247809 247810

दशमलव से हेक्साडेसिमल में मूल्यों को बदलने की कोशिश कर रहा है।

फंक्शन या तो .bashrc या शेल स्क्रिप्ट में परिभाषित किया गया है।

awk '{print $1 ; d2h($2)}' file

awk: अपरिभाषित फ़ंक्शन d2h इनपुट रिकॉर्ड नंबर 1, फ़ाइल फ़ाइल स्रोत लाइन नंबर 1 को कॉल करना

जवाबों:


27

system()फ़ंक्शन का उपयोग करने का प्रयास करें :

awk '{printf("%s ",$1); system("d2h " $2)}' file

आपके मामले systemमें कॉल d2h 247808और फिर इस कमांड के printfआउटपुट को आउटपुट में जोड़ देगा :

Mike 3C800

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

के बजाय systemउपयोग के रूप shमें bashमैं का उपयोग करने के लिए एक रास्ता नहीं मिल सकता है .bashrc। लेकिन आप अभी भी अपने वर्तमान बैश स्क्रिप्ट से कार्यों का उपयोग कर सकते हैं:

#!/bin/bash
d2h() {
    # do some cool conversion here
    echo "$1" # or just output the first parameter
}
export -f d2h
awk '{printf("%s ",$1); system("bash -c '\''d2h "$2"'\''")}' file

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

मुझे पता नहीं क्यों, लेकिन यह मेरे Ubuntu 16.04 पर काम नहीं कर रहा है। यह अजीब है, क्योंकि यह Ubuntu 14.04 पर काम करता था।


यह काम कर सकता है यदि d2hएक निष्पादन योग्य था, लेकिन यह नहीं कि यह "फ़ंक्शन या तो .bashrc या शेल स्क्रिप्ट में परिभाषित है"।
माइकल होमर

@MichaelHomer हाँ, आप सही हैं। आपकी टिप्पणी के लिए धन्यवाद मुझे एहसास हुआ कि मैंने उस सवाल का जवाब दिया है जो किसी ने नहीं पूछा। लेकिन मुझे वर्तमान स्क्रिप्ट (और संभवतः अन्य स्क्रिप्ट से source) के माध्यम से फ़ंक्शंस का उपयोग करने का एक तरीका मिल गया है, लेकिन मैं यह पता नहीं लगा सकता कि यह क्यों नहीं करता है .bashrc
एरिकिलिमानो

2
$2शेल कोड के रूप में व्याख्या किए जा रहे सिरों की सामग्री के रूप में यह एक कमांड इंजेक्शन भेद्यता भी है ।
स्टीफन चेज़लस

8

आप aw से bash को कॉल कर सकते हैं और इसके आउटपुट का उपयोग कर सकते हैं। यदि यह बहुत बार होता है, तो प्रदर्शन के दृष्टिकोण से यह स्पष्ट रूप से खतरनाक है। आदमी पृष्ठ का हवाला देते हुए:

command | getline [var]

रन कमांड पाइपिंग आउटपुट को $ 0 या var में,

कमांड एक बैश स्क्रिप्ट होगी जिसमें फ़ंक्शन की परिभाषा होती है और फ़ंक्शन को निष्पादित करता है।


हाउक लैजिंग, बहुत अच्छा!
जेजाओ

मैंने कई बार इसका उपयोग किया है, और यह अच्छी तरह से काम करता है।
डेव रिक्स

4

ऐसा करने का प्रयास करें:

awk '{print $1 ; printf "%x\n", $2}' file

AFAIK, आप aw में bash फ़ंक्शन का उपयोग नहीं कर सकते हैं लेकिन केवल एक स्क्रिप्ट है। यदि आवश्यक हो तो आप एक awk फ़ंक्शन का उपयोग कर सकते हैं।


3

उपयोगकर्ता परिभाषित बश फ़ंक्शन को awk के अंदर उपयोग करना

अस्वीकरण: मुझे एहसास है कि ओपी ऐसा करने की कोशिश नहीं कर रहा है, लेकिन Google मेरे जैसे अन्य लोगों को इस जवाब पर ले जाएगा।

परिस्थिति

आपके पास एक bashस्क्रिप्ट है जो फ़ंक्शंस के साथ आयोजित की जाती है (क्योंकि आप अपने आप से या [सबसे] सहकर्मियों से घृणा नहीं करते हैं) और उन फ़ंक्शंस में से कम से कम 1 को दूसरे को भीतर से कॉल करने की आवश्यकता होती है awk

समाधान

लिपि

#!/bin/env bash

# The main function - it's a sound pattern even in BASH
main(){
    # In the awk command I do some tricky things with single quotes. Count carefully...
    # The first $0 is outside the single quotes so it is the name of the current bash script.
    # The second $0 is inside the single quotes so it is awk's current line of input.
    awk '{printf("%s. ", ++c); system("'$0' --do"); print $0}'<<-PRETEND_THIS_IS_AN_INPUT_STREAM
        and
        and
        well
    PRETEND_THIS_IS_AN_INPUT_STREAM
}

# functionized to keep things DRY
doit(){
    echo -n "doin' it "
}


# check for a command switch and call different functionality if it is found
if [[ $# -eq 1 && $1 == "--do" ]];
then
        doit
else
        main
fi

उत्पादन

$ ./example.sh
1. doin' it and
2. doin' it and
3. doin' it well

मैं क्वींस का प्रतिनिधित्व करता हूं, उसे ब्रुकलिन
ब्रूनो ब्रोंस्की

3

awkawkकार्य चला सकते हैं । bashफ़ंक्शंस को चलाने के लिए , आपको awkएक bashशेल निष्पादित करना होगा , जो bashउस फ़ंक्शन की परिभाषा की व्याख्या करने के लिए, और उस फ़ंक्शन को कॉल करें, awkजिसे तर्कों के रूप में निकाले गए मान के साथ निकाला जाए ।

तुच्छ नहीं।

bashनिर्यात कार्यों का समर्थन करता है इसलिए यह बाद के इनवोकेशन में उपलब्ध है bash, इसलिए यह फ़ंक्शन की परिभाषा को bashइनवॉइस द्वारा पास करने का एक तरीका है awk:

export -f d2h

केवल तरीकों के लिए awkएक कमांड (निष्पादित करने के लिए bashयहाँ) के साथ अपने हैं system("cmd"), या print... | "cmd"या "cmd" | getline। सभी मामलों में, awkव्याख्या करने के लिए एक शेल चलाता है cmd, लेकिन यह होगा sh, नहीं bash। तो आपको इसके लिए एक कमांड लाइन बनाने की आवश्यकता है, shजो कि एक bashइनवोकेशन है जो bashफ़ंक्शन को लागू करने के लिए कमांड लाइन की व्याख्या करती है, इसलिए आपको उद्धरण के साथ सावधान रहने की आवश्यकता है:

export -f d2h
<file awk -v q="'" '
  function shquote(s) {
    gsub(q, q "\\" q q, s)
    return q s q
  }
  {print $1; system("bash -c '\''d2h \"$1\"'\'' bash " shquote($2))}'

इसका मतलब है कि प्रत्येक पंक्ति के लिए एक shऔर एक चल रहा है bash, इसलिए काफी अक्षम है। यह bashपढ़ने और विभाजन के साथ होने की तुलना में बहुत अधिक अक्षम होने का अंत होगा while read loop:

(unset IFS; while read -r a b rest; do
  printf '%s\n' "$a"
  d2h "$b"
 done < file)

0

इससे आपको अच्छे मौके मिलेंगे।

cat ../logs/em2.log.1 |grep -i 192.168.21.15 |awk '{system("date"); print $1}'

सिस्टम फ़ंक्शन आपको awk स्ट्रीम के भीतर बैश कमांड को पार्स करने में सक्षम बनाता है।


0

बस एक त्वरित हैक @HaLLaging प्रदर्शित करता है command|getline :

1) इनपुट होने दें:

Dear friends
my name is `id -nu` and
today is `date "+%Y-%m-%d"`.

इनपुट में शेल सिंटैक्स के बाद,

`command`

इनलाइन कमांड को उसके निष्पादन के परिणामस्वरूप प्रतिस्थापित करने के लिए प्रयोग किया जाता है ।

2) हम इनलाइन शेल कमांड का विस्तार कर सकते हैं:

#!/usr/bin/gawk -f

BEGIN  { FS ="`";        }
NF==3  { $2 | getline $2 }
       { print           }

3) उपयोग (सामान्य chmod के बाद):

$ expand-inline input
Dear friends
my name is jjoao and
today is 2018-01-15.
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.