どういうわけかAWK内でbash関数を使用することは可能ですか?
ファイルの例(string、int、int、int)
Mike 247808 247809 247810
値を10進数から16進数に変換しようとしています。
.bashrcまたはシェルスクリプトで定義された関数。
awk '{print $1 ; d2h($2)}' file
awk:未定義の関数d2h入力レコード番号1、ファイルファイルソース行番号1を呼び出しています
system()
関数を使用してみてください:
awk '{printf("%s ",$1); system("d2h " $2)}' file
あなたの場合、system
はd2h 247808
を呼び出し、次にこのコマンドの出力をprintf
出力に追加します。
Mike 3C800
編集:
system
はsh
ではなくbash
を使用しているため、.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:
理由はわかりませんが、これは私のUbuntu 16.04では機能しません。これは以前はUbuntu 14.04で機能していたため、奇妙です。
Awkからbashを呼び出して、その出力を使用できます。それが頻繁に発生すると、パフォーマンスの観点から明らかに危険です。 manページを引用する:
command | getline [var]
$ 0またはvarに出力をパイプするコマンドを実行します。
コマンドは、関数定義を含み、関数を実行するbashスクリプトです。
awk
はawk
関数を実行できます。 bash
関数を実行するには、awk
シェルを実行するためにbash
が、その関数の定義を解釈するためにbash
が必要であり、 awk
によって抽出された値を引数として渡した関数。
ささいなことではありません。
bash
は関数のエクスポートをサポートしているため、その後のbash
の呼び出しで使用できます。これは、bash
によって呼び出されたawk
に関数の定義を渡す1つの方法です。 :
_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))}'
_
これは、各行に1つのsh
と1つのbash
を実行することを意味するため、非常に非効率になります。その場合、bash
に_while read loop
_を使用して読み取りと分割を行わせるよりも、はるかに非効率的になります。
_(unset IFS; while read -r a b rest; do
printf '%s\n' "$a"
d2h "$b"
done < file)
_
これを試してください:
awk '{print $1 ; printf "%x\n", $2}' file
AFAIK、あなたはawkでbash関数を使うことはできませんが、スクリプトだけを使うことができます。必要に応じてawk関数を使用できます。
免責事項:これは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
これはあなたに良いチャンスを与えるでしょう。
cat ../logs/em2.log.1 |grep -i 192.168.21.15 |awk '{system("date"); print $1}'
システム関数を使用すると、awkストリーム内のbashコマンドを解析できます。
@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.