"<topic>...<topic>"
매핑 구성을 통해 잘못된 문자를 대체하여 데이터베이스 테이블 이름에 매핑되어야 하는 주제를 나타내는 문자열을 보유하는 bash에 변수가 있습니다 .
필요한 매핑 형식은 다음과 같습니다 "topic1:table1,topic2:table2"
. 즉, 이것이 제가 필요한 출력입니다.
맥락상 이는 구성 항목입니다.눈송이 카프카 커넥터이는 주제에서 테이블로 데이터를 스트리밍하는 데 도움이 되며, 중요한 것은 허용되는 문자 측면에서 테이블 이름이 더 제한된다는 것입니다.
가장 간단한 경우 잘못된 문자는 하이픈이며 밑줄로 변환해야 합니다.
예를 들어 "foo-bar,boo-baz"
입력 문자열의 경우 필수 대답은 다음과 같습니다.
"foo-bar:foo_bar,boo-baz:boo_baz"
.
Python에서는 다음과 같이 간단합니다.
import sys
s = sys.argv[1]
print(','.join(p + ':' + p.replace('-', '_') for p in s.split(',')))
추가 소프트웨어 설치를 피하기 위해 쉘 스크립트 도구를 기반으로 한 솔루션을 찾고 있습니다.
예를 들어 나는 sed를 안다라벨 포함이것이 문제 해결에 도움이 될 수 있다고 생각하지만 아직 해결책을 찾지 못했습니다.
답변1
다음과 같은 변수에 입력이 있다고 가정합니다 TOPICS
.
사용 sed
:
sed 's/[^,]\+/\0:\0/g; :a s/:\([^-,]\+\)-/:\1_/g; ta' <<<"$TOPICS"
s/[^,]\+/\0:\0/g
- 각 주제(쉼표를 포함하지 않는 단어)를 선택하고 그 뒤에 동일한 단어와 콜론을 추가합니다. 이 부분 이후의 결과는 다음과 같습니다.foo-bar:foo-bar,boo-baz:boo-baz
:a s/:\([^-,]\+\)-/:\1_/g
- 각 콜론 뒤의 하이픈을 밑줄로 바꿉니다.
- 이 시점에서는 각 주제의 첫 번째 하이픈만 대체됩니다. 따라서 예를 들어 주제 중 하나가 이고
foo-bar-baz
첫 번째 단계 이후에 has를 사용하는 경우foo-bar-baz:foo-bar-baz
결과는 이 단계 이후가 됩니다foo-bar-baz:foo_bar-baz
.
ta
- 가장 최근 대체가 성공한 경우(하이픈은 밑줄로 대체됨) - 태그를 반환하여:a
대체할 항목이 더 있는지 확인합니다. 이는 주제에 하이픈이 여러 개 포함되는 것을 방지하기 위한 것입니다. 2단계에서 교체가 이루어지지 않은 경우 레이블로 다시 분기하지 말고 다음 줄로 계속 진행하세요.
- 예:
foo-bar-baz:foo_bar-baz
이전 예는 이제 가 됩니다foo-bar-baz:foo_bar_baz
.
사용 awk
:
awk 'BEGIN {ORS=RS=","} { if (gsub( /\n$/, "" )) ORS="\n"; NEW=$0; gsub("-", "_", NEW); print $0":"NEW}' <<<"$TOPICS"
RS
(입력 레코드 구분 기호) 및ORS
(출력 레코드 구분 기호)가 로 설정됩니다,
. 이렇게 하면awk
각 주제가 별도의 행으로 처리됩니다.if (gsub( /\n$/, "" )) ORS="\n"
- 단어의 마지막 문자가\n
(개행)이면 제거합니다.gsub
대체 번호(1)를 반환하고 마지막 단어에서는 읽은 단어 뒤에 새 줄을 인쇄하지 않고 마지막 줄(출력 레코드 구분 기호)로만 인쇄합니다.gsub("-", "_", NEW)
- 하이픈을 밑줄로 바꾸세요.
awk
++ 사용 :sed
tr
여기에는 추가 명령이 있지만 읽기가 더 쉬울 것입니다.
echo "$TOPICS" \
| tr ',' '\n' \
| awk '{NEW=$0; gsub("-", "_", NEW); print $0":"NEW}' \
| tr '\n' ',' \
| sed 's/,$/\n/'
tr ',' '\n'
- 새 줄로 단어를 분리하는 것부터 시작하세요.awk
매핑을 인쇄합니다.tr '\n' ','
- 줄 바꿈을 쉼표로 바꾸십시오.sed 's/,$/\n/'
- 마지막 쉼표를 제외하고는 뉴라인 문자로 대체되어야 합니다.
답변2
문자열만 조작한다고 가정하면 이를 달성하는 한 가지 방법은 다음과 같습니다.
#!/usr/bin/env bash
p="foo-bar,boo-baz"
IFS=',' read -ra arr <<< "$p"
result=()
for item in "${arr[@]}"; do
result+=("${item}:${item//-/_}")
done
end_result=$(printf '%s,' "${result[@]}")
echo "${end_result%,*}"
문자열 조작에 대해 배우고 싶다면 다음을 참조하세요.https://mywiki.wooledge.org/BashFAQ/100
답변3
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ echo 'foo-bar,boo-baz' |
awk -F',' '{for (i=1; i<=NF; i++) {t=$i; gsub(/-/,"_",t); printf "%s:%s%s", $i, t, (i<NF ? FS : ORS)}}'
foo-bar:foo_bar,boo-baz:boo_baz
또는 원하는 경우:
$ echo 'foo-bar,boo-baz' |
awk -v RS=',' '{t=$1; gsub(/-/,"_",t); printf "%s:%s%s", $1, t, (sub(/\n$/,"") ? ORS : RS)}'
foo-bar:foo_bar,boo-baz:boo_baz
입력이 개행(POSIX에 따르면 유효한 텍스트 파일이어야 함)으로 끝나지 않으면 두 번째 것은 실패합니다.