AWK 내에서 bash 쉘 기능 사용


24

어떻게 든 AWK 내에서 bash 기능을 사용할 수 있습니까?

예제 파일 (문자열, int, int, int)

Mike 247808 247809 247810

값을 10 진수에서 16 진수로 변환하려고합니다.

.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대신 bashI에 액세스 할 수있는 방법을 찾을 수 없습니다 .bashrc. 그러나 현재 bash 스크립트의 함수를 계속 사용할 수 있습니다.

#!/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 :

왜 그런지 모르겠지만 우분투 16.04에서 작동하지 않습니다. 우분투 14.04에서 작동했기 때문에 이상합니다.


d2h실행 파일 인 경우 에는 작동 하지만 ".bashrc 또는 쉘 스크립트에 정의 된 기능"인 경우에는 작동 하지 않습니다.
Michael Homer

@MichaelHomer 네, 맞습니다. 귀하의 의견에 감사드립니다. 그러나 현재 스크립트 (및 다른 스크립트를 통해 source) 에서 함수를 사용하는 방법을 찾았 지만 왜 작동하지 않는지 알 수 없습니다 .bashrc.
akarilimano

2
또한 내용이 $2쉘 코드로 해석되기 때문에 명령 주입 취약점이기도합니다 .
Stéphane Chazelas

8

awk에서 bash를 호출하고 출력을 사용할 수 있습니다. 성능이 너무 자주 발생하면 성능 측면에서 위험합니다. 매뉴얼 페이지 인용 :

command | getline [var]

출력을 $ 0 또는 var로 파이핑 명령을 실행하십시오.

command는 함수 정의를 포함하고 함수를 실행하는 bash 스크립트입니다.


Hauke ​​Laging, 매우 시원합니다!
JJoao

나는 이것을 여러 번 사용했으며 잘 작동합니다.
데이브 릭스

4

이것을 시도하십시오 :

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

AFAIK, awk에서는 bash 함수를 사용할 수 없지만 스크립트 만 사용할 수 있습니다. 필요한 경우 awk 기능을 사용할 수 있습니다.


3

awk 내부에서 사용자 정의 bash 함수 사용

면책 조항 : 이것은 OP가하려고하는 것이 아니라는 것을 알고 있지만 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

나는 퀸즈, 그녀는 브루클린에서 자란 표현한다
브루노 Bronosky에게

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그 A는 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 스트림 내에서 bash 명령을 구문 분석 할 수 있습니다.


0

빠른 해킹은 @HaukeLaging을 보여줍니다 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.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.