他のファイルの値にファイルを変更する - Bashスクリプト

他のファイルの値にファイルを変更する - Bashスクリプト

2つのファイルをパラメータとして使用し、.csvファイルの値に.svgファイルを変更するスクリプトを作成しようとしています。 Csvファイルは、数値、色という2つの値を持つ行で構成されています。 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値を入力する必要があります。役に立つことの1つは次のとおりです。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スタイルを好む。

私たちができるもう1つのことは、キャプチャグループを使用して複数回sed入力するのを防ぐことです。id="$id"

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

一致するコンテンツを\(キャプチャし、置き換えられた文字列に戻します。 *)MS-Windowsでスクリプトを書いたことがある場合は、コマンドライン(CMDでもPowershellでも)がスクリプトで同じコマンドを実行するのとは異なる動作をし、一般的に目立たない残念な状況を知っています。これは\)\1いいえこれは Bash などの Unix スクリプトシェルの場合です。

関連情報