回答:
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で動作していたため、奇妙です。
source
)の関数を使用する方法を見つけましたが、なぜ機能しないのかはわかりません.bashrc
。
$2
シェルコードとして解釈されるため、コマンドインジェクションの脆弱性でもあります。
免責事項:これは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
awk
awk
関数を実行できます。それを実行するために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
で1つずつ実行することを意味するbash
ため、非常に効率が悪くなります。それはbash
、読み取りと分割を行うよりもはるかに非効率になりますwhile read loop
:
(unset IFS; while read -r a b rest; do
printf '%s\n' "$a"
d2h "$b"
done < file)
ちょっとしたハックで@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.
d2h
実行可能ファイルであれば機能しますが、「。bashrcまたはシェルスクリプトで定義された関数」では機能しません。