나는 작은 bash 스크립트를 작성하고 sed
일부 HTML 페이지에서 일부 URL을 추출하는 데 사용했습니다.
sed 결과를 변수로 가져와 매번 다시 읽는 것을 방지하기 위해 간단히 3개의 함수를 만들고 함께 파이프했습니다.
first_function $1 | second_function | third_function
다음과 같이 표현해 보겠습니다.
- 첫 번째 함수는 주어진 목록에서 항목 URL을 찾습니다.링크 주소(
$1
) - 두 번째 함수는 각 파이프라인 URL에서 이미지를 추출합니다.
src
- 세 번째 함수는 출력 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
파이프의 양면은 서로 다른 프로세스에 있습니다. 이러한 프로세스 간에 변수를 공유할 수 없습니다. 데이터를 공유하려면 데이터를 파이프하거나 대체 통신 채널을 사용해야 합니다. 대체 통신 채널이 필요한 경우 셸의 기능을 넘어서는 경우 실제 프로그래밍 언어로 전환하세요.
여기에서는 두 번째 파이프라인에서 병렬화하는 것이 나 lot_url
에게는 img_url
좋은 해결책인 것 같습니다 . 나는 그것들을 같은 줄로 전달할 것입니다. URL이 올바르게 이스케이프되었다고 가정하면 특정 따옴표가 필요하지 않으며 두 따옴표를 같은 줄에 전달할 수 있습니다. 이는 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의 대답을 받아들였습니다. 분명히 몇 년 전만 해도 저는 깨닫지 못했습니다.이건 또 다른 거야이것은 나와 비슷한 접근 방식을 보여주며 이 목적에 더 적합하다고 생각합니다.