그래서 얼마전에 봤는데이것두 "마커" 사이의 텍스트를 추출하기 위한 스니펫:
# Usage: extract file "opening marker" "closing marker"
while IFS=$'\n' read -r line; do
[[ "$extract" && "$line" != "$3" ]] &&
printf '%s\n' "$line"
[[ "$line" == "$2" ]] && extract=1
[[ "$line" == "$3" ]] && extract=
done < "$1"
(여기서는 함수에서 무작위로 제거하고 이라는 파일에 넣었습니다. extract
) 이제는 "대부분의" 태그 쌍에서 제대로 작동합니다. 그러나 나는 그것이 항상 작동하는 것은 아니라는 것을 알았습니다.
N개의 반복 문자가 포함된 원본 조각의 예를 따르세요(SO의 형식 오류로 인해 "`" 대신 "#" 사용).
###sh
test
###
이것은 작동 extract file '###sh' '###'
하지만 다음 마크업을 사용하는 경우:
###
test
###
그렇게 했는데 extract file '###' '###'
작동하지 않나요?
스크립트의 조건이 올바르게 평가되는 것을 볼 수 있지만 변수는 사용된 경우 extract
와 같습니다 .1
set -x
어떻게 되어가나요?
추신: 물론 "작동하지 않는다"는 말은 작동하지 않으면 인스턴스에 아무 것도 인쇄하지 않는다는 의미입니다.
위의 두 가지 예제 출력해서는 안 된다태그 포함(두 태그 사이에서 추출된 텍스트만)...
가능하다면 bash/shell 솔루션을 선호합니다.
답변1
[[ "$line" == "$2" ]]
다른 사람들이 귀하의 질문에 대한 설명에서 언급했듯이 시작 조건이 충족 되면 extract
1로 설정되지만 다음 줄에서 [[ "$line" == "$3" ]]
종료 조건도 충족되면 스크립트가 extract
빈 문자열로 재설정되기 때문에 스크립트가 작동하지 않습니다 .
고정된 스크립트는 다음과 같습니다.
# Usage: extract file "opening marker" "closing marker"
while IFS=$'\n' read -r line; do
if [ "$extract" ]; then
if [[ "$line" == "$3" ]]; then
extract=
else
printf '%s\n' "$line"
fi
elif [[ "$line" == "$2" ]]; then
extract=1
fi
done < "$1"
그리고 이것이 필요한 경우 @Freddy가 제안한 대로 인쇄되는 텍스트에 닫는 태그가 있어야 하는 약간 수정된 버전이 있습니다.
# Usage: extract file "opening marker" "closing marker"
while IFS=$'\n' read -r line; do
if [ "$extract" ]; then
if [[ "$line" == "$3" ]]; then
printf '%s\n' "${lines[@]}"
lines=() extract=
else
lines+=( "$line" )
fi
elif [[ "$line" == "$2" ]]; then
extract=1
fi
done < "$1"
(행은 배열에 누적되며 lines
끝 표시가 나타날 때만 인쇄됩니다)
답변2
$2가 표시될 때마다 추출 변수에 전환 논리를 추가합니다. 지적해 주신 xhiene에게 감사드립니다!
[[ $line == $2 ]] && case $extract in '') extract=1;; *) extract=; esac
이제 추출 변수에 대한 $3 종속성을 제거합니다.
HTH.