문자 대체가 포함된 맵을 생성하기 위한 쉘 스크립트(예: sed)

문자 대체가 포함된 맵을 생성하기 위한 쉘 스크립트(예: sed)

"<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"
  1. s/[^,]\+/\0:\0/g- 각 주제(쉼표를 포함하지 않는 단어)를 선택하고 그 뒤에 동일한 단어와 콜론을 추가합니다. 이 부분 이후의 결과는 다음과 같습니다.foo-bar:foo-bar,boo-baz:boo-baz
  2. :a s/:\([^-,]\+\)-/:\1_/g- 각 콜론 뒤의 하이픈을 밑줄로 바꿉니다.
  • 이 시점에서는 각 주제의 첫 번째 하이픈만 대체됩니다. 따라서 예를 들어 주제 중 하나가 이고 foo-bar-baz첫 번째 단계 이후에 has를 사용하는 경우 foo-bar-baz:foo-bar-baz결과는 이 단계 이후가 됩니다 foo-bar-baz:foo_bar-baz.
  1. 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"
  1. RS(입력 레코드 구분 기호) 및 ORS(출력 레코드 구분 기호)가 로 설정됩니다 ,. 이렇게 하면 awk각 주제가 별도의 행으로 처리됩니다.
  2. if (gsub( /\n$/, "" )) ORS="\n"- 단어의 마지막 문자가 \n(개행)이면 제거합니다. gsub대체 번호(1)를 반환하고 마지막 단어에서는 읽은 단어 뒤에 새 줄을 인쇄하지 않고 마지막 줄(출력 레코드 구분 기호)로만 인쇄합니다.
  3. gsub("-", "_", NEW)- 하이픈을 밑줄로 바꾸세요.

awk++ 사용 :sedtr

여기에는 추가 명령이 있지만 읽기가 더 쉬울 것입니다.

echo "$TOPICS" \
 | tr ',' '\n' \
 | awk '{NEW=$0; gsub("-", "_", NEW); print $0":"NEW}' \
 | tr '\n' ',' \
 | sed 's/,$/\n/'

  1. tr ',' '\n'- 새 줄로 단어를 분리하는 것부터 시작하세요.
  2. awk매핑을 인쇄합니다.
  3. tr '\n' ','- 줄 바꿈을 쉼표로 바꾸십시오.
  4. 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에 따르면 유효한 텍스트 파일이어야 함)으로 끝나지 않으면 두 번째 것은 실패합니다.

관련 정보