표준 sed는 쉘을 호출 할 수 없습니다 ( GNU sed에는 비 임베디드 Linux 만 신경 쓰는 경우 확장 기능이 있습니다 ). sed 외부에서 일부 처리를 수행해야합니다. 몇 가지 해결책이 있습니다. 모두 신중하게 인용해야합니다.
값을 어떻게 확장할지 정확히 알 수는 없습니다. 예를 들어 라인이
foo hello; echo $(true) 3
다음 중 어느 것이 출력되어야합니까?
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<hello; echo 3>
k=<foo> value=<foo hello
3>
아래 몇 가지 가능성에 대해 설명하겠습니다.
순수한 껍질
쉘이 입력을 한 줄씩 읽고 처리하도록 할 수 있습니다. 이것은 가장 간단한 솔루션이며 짧은 파일의 경우 가장 빠릅니다. 이것은 귀하의 요구 사항“ echo \2
”에 가장 가까운 것입니다 .
while read -r keyword value; do
echo "k=<$keyword> v=<$(eval echo "$value")>"
done
read -r keyword value
세트 $keyword
최초의 공백으로 구분 된 라인의 단어와에 $value
선 마이너스 후행 공백의 나머지.
변수 참조를 확장하지만 명령 대체 외부에서 명령을 실행하지 않으려면 here document$value
안에 넣으 십시오 . 나는 이것이 당신이 정말로 찾고있는 것이라고 생각합니다.
while read -r keyword value; do
echo "k=<$keyword> v=<$(cat <<EOF
$value
EOF
)>"
done
껍질에 파이프 sed
입력을 쉘 스크립트로 변환하고 평가할 수 있습니다. Sed는 쉽지는 않지만 작업에 달려 있습니다. " echo \2
"요구 사항에 따라 (키워드에서 작은 따옴표를 이스케이프해야 함) :
sed -e 's/^ *//' -e 'h' \
-e 's/[^ ]* *//' -e 'x' \
-e 's/ .*//' -e "s/'/'\\\\''/g" -e "s/^/echo 'k=</" \
-e 'G' -e "s/\n/>' v=\\</" -e 's/$/\\>/' | sh
here 문서와 함께 키워드를 이스케이프 처리해야합니다 (그러나 다르게).
{
echo 'cat <<EOF'
sed -e 's/^ */k=</' -e 'h' \
-e 's/[^ ]* *//' -e 'x' -e 's/ .*//' -e 's/[\$`]/\\&/g' \
-e 'G' -e "s/\n/> v=</" -e 's/$/>/'
echo 'EOF'
} | sh
데이터가 많은 경우 가장 빠른 방법입니다. 각 라인마다 별도의 프로세스를 시작하지 않습니다.
어 wk
sed 작업에 awk를 사용한 것과 동일한 기술. 결과 프로그램은 훨씬 더 읽기 쉽습니다. "로 이동echo \2
"로 이동 :
awk '
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\047/, "\047\\\047\047", $1);
print "echo \047k=<" kw ">\047 v=\\<" $0 "\\>";
}' | sh
here 문서 사용하기 :
awk '
NR==1 { print "cat <<EOF" }
1 {
kw = $1;
sub(/^ *[^ ]+ +/, "");
gsub(/\\\$`/, "\\&", $1);
print "k=<" kw "> v=<" $0 ">";
}
END { print "EOF" }
' | sh