私は小さなbashスクリプトを書いて、sed
いくつかのHTMLページからいくつかのURLを抽出するために使用しました。
sed 結果を変数に取り込み、毎回再読み込みを防ぐために、3つの関数を作成し、一緒にパイプしました。
first_function $1 | second_function | third_function
次のように表現してみましょう。
- 最初の関数は、与えられたリストからアイテムURLを探します。リンクアドレス(
$1
) - 2番目の関数は、各パイプラインURLから画像を抽出します。
src
- 3番目の関数は出力HTMLを組み合わせます。
これでそれをエコーし$lot_url
てHTMLにすべて入れるsecond_function
ことができます。read
third_function
$img_url
もっときれいになるアクセス可能なグローバル変数で作成できる場合 second_function
しかし、third_function
私はできないようです。
これは、関数間で渡される値の数が増えるほど必要になります。
完全なサンプルコードは次のとおりです。
first_function(){
curl -s "$1" | sed -nr '
#extract sub urls
'
}
second_function(){
while read lot_url; do
echo "$lot_url"
curl -s "$lot_url" | sed -nr '
#extract img src
'
done
}
third_function(){
while read lot_url; read img_url; do
echo "<a href="$lot_url"><img src="$img_url" /></a>"
done
}
first_function "$1" | second_function | third_function
答え1
パイプの両面は異なるプロセスにあります。これらのプロセス間で変数を共有することはできません。データを共有するには、データをパイプするか、代替通信チャネルを使用する必要があります。代替通信チャネルが必要な場合シェルの機能を超えた場合は、実際のプログラミング言語に切り替えてください。
ここでは、2番目のパイプラインで並列化することが私lot_url
にとってはimg_url
良い解決策のようです。私はそれらを同じ行に渡します。 URLが正しくエスケープされたと仮定すると、特定の引用符は必要なく、2つの引用符を同じ行に渡すことができます。これはimg_url
それぞれに可変数のsを許可するという利点がありますlot_url
。
second_function(){
while read lot_url; do
echo "$lot_url"
curl -s "$lot_url" | sed -nr -e '
#extract img src
' -e "s>^>$lot_url >"
done
}
third_function(){
while read lot_url img_url; do
echo "<a href="$lot_url"><img src="$img_url" /></a>"
done
}
答え2
ここではwhileループは大丈夫だと思います。とにかく繰り返すたびに実行可能ファイルを呼び出すので、実際に違いがあるとは思いません。このようにしてできる必要なグローバル変数を共有します。良い:
source_cmd |
while read var
do fn1 "$var" |
fn2 "$var"
done
しかし、ワークフローを少し変更する方が良いと思いました。この機能は配列ベースのシェルコマンドセットに過ぎません。このような配列は使用しないので、コマンドセットを指す一般的な目的に使用する必要があります。私が見ることができる最も一般的なものですcurl ... | sed ...
。引数を取る関数として作成します。したがって、結果は次のようになります。
curl_sed() { url=$1 && shift
curl -s "$url" | sed -nr "$*"
}
fn() { URL=$1 && shift
set -- '#extract sub url sed script' \
'#extract img src sed script'
curl_sed "$URL" "$1" |
while read lot_url
do IFS='
'; printf '<a href="'"$lot_url"'"><img src="%s" /></a>\n' \
$(curl_sed "$lot_url" "$2")
done
}
あなたはこの質問に対するGilesの答えを受け入れました。明らかに、数年前だけでも私は気付かなかった。これは別のものです。これは私と同様のアプローチを示しており、この目的に適していると思います。