sed 패턴 일치를 사용하여 ASCII 십진수 표현을 쉼표로 구분된 목록으로 바꾸고 싶습니다. 패턴을 csv 정수 문자열로 변환하는 작업은 bash 함수 내에서 수행됩니다. 함수가 제 역할을 하고 있지만 sed 호출에 통합하는 데 문제가 있습니다. 샘플 코드는 다음과 같습니다.
#!/bin/bash
xx(){
##turns a string into its
##ascii-integer representation as a comma-separated list
##ignores double quotes at the start and end
n=0;o=""
for((k=1;k<$(echo $1 | wc -c);k++))
do
x=$(echo $1 | cut -b"$k")
a=$(printf '%d\n' "'$x" )
if [ $a = 34 ]
then
continue
else
n=$(($n+1))
if [ $n = 1 ]
then
o=$a
else
o=$(echo $o","$a)
fi
fi
done
o=$(echo '('$o')')
echo $o
}
##this works
xx "\"bla\""
##this does not work
y=$(echo "\"bla_x\"" | sed -e "s/bla/$(xx &)p")
기능은 작동하지만 sed 통합이 실패합니다. 인터넷 검색을 통해 이것이 원칙적으로 가능해야 한다는 인상을 받았으므로 아마도 작은 구문 오류일 수도 있습니다.
어떤 도움이라도 대단히 감사하겠습니다.
모두 제일 좋다
참고: 최종 애플리케이션에서 sed에 대한 입력은 reg-exp 패턴(예: "k_[[:alnum:]]{5}")이 있는 파일이며, 이는 csv 연결로 대체됩니다. 따라서 궁극적으로 "xx"는 sed에서 호출되어야 합니다.
답변1
sed 호출을 주의 깊게 살펴보세요. s/// 명령의 닫는 슬래시가 누락되어 있습니다. 다음으로 큰따옴표를 사용하므로 sed가 실행되기 전에도 큰따옴표 보간으로 인해 s/// 명령의 rhs가 채워집니다. 당신이 원하는 것이 아닌가요? 하지만 그래도 골대를 넘을 수는 없습니다.
/e
명령에는 잘 알려지지 않은 기호가 있습니다 GNU sed's s///
. 이 경우 의사가 지시한 것이 바로 이것이다. 그것이 하는 일은 rhs 실행 시 제공된 쉘 코드를 기반으로 s/// 명령의 rhs를 동적으로 구성하고 이를 출력으로 바꾸는 것입니다. 참고: 전체 패턴 공간이 일치해야 합니다.
또한 어린이가 사용할 수 있도록 사용자 정의 함수를 내보내야 합니다.
#this does not work
##this is what YOU wrote
y=$(echo "\"bla_x\"" |
sed -e "s/bla/$(xx &)p")
##this now WORKS
export -f xx
y=$(
echo '"bla_x"' |
sed -Ee '
s/^.(.*)(_x).$/echo "$(xx '"\1"')\2"/e
'
)
echo "$y"
(98,108,97)_x
sed 명령에서 작은따옴표 사용에 유의하세요.
답변2
내가 올바르게 이해했다면 다음을 사용하여 기능을 단순화할 수 있습니다 printf
.
xx() {
# create an array to store every character of the word
declare -a arr
# loop the word to every char, removing quotes
for i in $(echo "${1//\"}" | grep -o .); do
# store the ascii value
arr+=($(printf "%d" "'$i"))
done
# create a variable with the values, comma separated
printf -v ascii "%s," "${arr[@]}"
# print the result adding the parenthesis and removing the last comma
echo "(${ascii%,})"
}
$ xx "\"bla\""
(98,108,97)
이제 xx
큰따옴표를 제거하되 sed
명령에서 따옴표가 없는 패턴("bla"가 아닌 bla)을 보내려고 하므로 다음 코드의 출력에 큰따옴표가 표시되는 것을 원하지 않으면 제거해야 합니다. 다른 방법:
p=bla
s="\"bla_x\""
c=$(xx "$p")
$ echo "$s" | sed "s/$p/$c/"
"(98,108,97)_x"