다른 파일의 값으로 파일 변경 - Bash 스크립트

다른 파일의 값으로 파일 변경 - Bash 스크립트

두 개의 파일을 매개변수로 사용하고 .csv 파일의 값으로 .svg 파일을 변경하는 스크립트를 작성하려고 합니다. Csv 파일은 숫자, 색상이라는 두 가지 값이 있는 행으로 구성됩니다. svg 파일에서 ID를 찾고 ID가 일치하는 줄에 색상을 추가해야 합니다. 변경 사항에 변수를 도입할 때 복잡해지기 때문에 내 문제가 sed 부분인지 또는 스크립트에 근본적으로 결함이 있는지 모르겠습니다. .

id=($(cut -f1 -d, $2))
colour=($(cut -f2 -d, $2))
file=$1
name=$(basename -s .svg $1)
name1=$(echo "$name""1")
cat $2 | while IFS=, read id colour; do 
sed -i "s/id=\"'"$id"'\"/id=\"'"$id"'\" style=\"fill:\"'"$colour"'\";\"/" "$1"
done

사용하면 sed -i 's/id="ca"/id="ca" style="fill:red;"/' data.svg파일이 변경되지만 "$id" 또는 "$id"로 "ca"를 변경하면 작동하지 않습니다.

나는 또한 이것을 시도했습니다 :

cat $2 | while IFS=, read id colour; do 
sed -i 's/id='"$id"'/id='"$id"' style="fill:red;"/' "$1"
done

내가 얻은 결과는 다음과 같습니다. <g id= style="fill:red;""hi"> 예상되는 결과는 다음과 같습니다.
<g id="hi" style="fill:red;">

$color를 sed에 넣으면 sed -i 's/id='"$id"'/id='"$id"' style="fill:'"$colour"';"/' "$1"다음과 같은 결과가 나옵니다:<g id= style="fill:;""hi">

답변1

  1. CSV를 변수로 읽어올 필요가 없으며 CSV를 직접 반복할 수 있습니다.
cat data.csv | while IFS=, read id colour; do # something with $id and $colour
  1. 이것은 var=$(echo text)약간 중복되므로 그냥 사용해야 합니다 var="text".

  2. struct 가 무슨 뜻인지 잘 모르겠지만 [ "grep -E..." ], 이는 기본적으로 테스트 중인 문자열이 비어 있지 않은지 여부를 테스트합니다. 이는 단순히 텍스트를 넣었기 때문이 아닙니다.

Bash 스크립트를 작성할 때 명령줄(*)에서 각 표현식을 차례로 테스트하고 예상한 대로 작동하는지 확인하는 것이 좋습니다. 이렇게 하면 많은 놀라움을 피할 수 있습니다. 좋은 스크립트를 작성하는 방법에 대한 경험이 많지 않은 상태에서 완전한 스크립트를 작성한 다음 이를 실행하는 것은 스스로를 공격하는 좋은 방법이 될 수 있습니다. 나는 수년간 bash 스크립트를 작성해 본 경험이 있지만 여전히 스크립트를 작성하기 전에 명령줄에서 많은 시도를 하고 실패합니다. 스크립트를 실행할 때 -x이를 실행하여 명령 추적을 활성화하는 것이 도움이 될 수 있습니다.

교체가 작동하지 않는 주된 이유는 SVG 파일이 "ID 속성에 대해 표현식과 같은 작은 따옴표가 아닌 큰 따옴표( )를 사용하기 때문이라고 생각합니다 sed.

쉘 스크립트에서 표현식을 구성할 때 sed모든 이스케이프를 처리하는 것은 종종 성가신 일입니다. 가능하다면 나는 일반적으로 sed표현식을 전혀 인용하지 않는 것을 좋아하는데, 이는 슬래시가 아닌 정규식 구분 기호를 자주 사용하는 이유 중 하나입니다(다음에 살펴보겠지만). SVG 속성에 대한 참조를 올바르게 식별 하면서 id및 표현식에 값을 입력 해야 합니다 . 도움이 될 수 있는 한 가지는 다음과 같습니다.coloursed

sed -i "s,id=\"$id\",id=\"$id\" style=\"fill:$colour;\"," "$1"

여기서는 표현식 주위에 큰따옴표를 사용합니다. 이를 통해 변수를 포함할 수 있습니다. 그리고 일치를 위해 큰따옴표를 이스케이프하여 쉘 문자열이 종료되는 것을 방지합니다.

또 다른 옵션은 sed서로 다른 인용 규칙을 사용하여 여러 문자열에서 표현식을 작성하는 것입니다.

sed -i 's,id="'"$id"'",id="'"$id"'" style="fill:'"$colour"';",' "$1"

여기에서는 모든 정적 텍스트를 작은따옴표로 묶은 다음 작은따옴표를 종료하고 큰따옴표로 묶인 문자열을 열어 변수를 구문 분석합니다. 이는 작은 따옴표로 묶인 문자열과 큰 따옴표로 묶인 문자열 사이에 공백이 없기 때문에 작동하며 공백이 없는 한 Bash는 모든 문자열을 단일 인수로 전달합니다 sed. 하지만 분명히 이것은 약간 혼란스럽습니다. A 스타일을 선호합니다.

우리가 할 수 있는 또 다른 일은 캡처 그룹을 사용하여 여러 번 sed입력하는 것을 방지하는 것입니다.id="$id"

sed -i "s,\(id=\"$id\"\),\1 style=\"fill:$colour;\"," "$1"

일치하는 콘텐츠를 \(캡처하여 교체 된 문자열에 다시 넣습니다. *) MS-Windows에서 스크립트를 작성해 본 적이 있다면 명령줄(CMD든 Powershell이든)이 스크립트에서 동일한 명령을 실행하는 것과 다르게 동작하고 일반적으로 눈에 잘 띄지 않는 실망스러운 상황을 알고 계실 것입니다. 이것은\)\1아니요이는 Bash와 같은 Unix 스크립팅 셸의 경우입니다.

관련 정보