sed:複数の-eまたはwhileループ?

sed:複数の-eまたはwhileループ?

値タプルを含むCSVファイルがあるため、ある値の発生回数を別の(大規模)ファイル内の他の値の発生回数に変更する必要があります。

これまで、私はしばらくの間読み出し[...] < foo.csvを実行してきましたが、基本的にCSVファイルの各行に対してsedを1回実行しました。

これはかなり長い時間がかかるので、whileループを変更して複数の-eステートメントの長い文字列を構成し、evalを使用して実行する必要があるかどうか疑問に思います。

明らかに試してみることができますが、誰かがsedが私が今までやったのと同じことをするかどうか、つまりすべての-eステートメントに対してファイルを実行しているかどうかを伝えることができれば、パフォーマンスが向上しないと思います。気にしません。

コメント後の編集:

デフォルトでは、次の操作を行います。

while read line
do
  old_user=echo $line | cut -d \; -f 2|tr -d \"
  new_user=echo $line | cut -d \; -f 4|tr -d \"

  if [ "$old_user" != "$new_user" ]
  then
    sed -i -e "s/^(.*ri:username=\")$old_user(\".*)$/\1$new_user\2/g" confluence/entities_converted.xml
  fi
done < usernames.csv

XMLファイルであることを見ると、その理由は多くの場合、XMLを解析して再構築するのが面倒だからです。だから...何度も実行するのsedではなく、複数のパラメータを設定する必要があるかどうか疑問に思います。sed-esed

usernames.csv良い

    "Full name";"Username";"Email";"New username"
    "Sune Mølgaard";"sune.molgaard";"[email protected]";"smo"

2番目の線のパスに沿って複数の線がある可能性があるため、円形です。最初の行は一致しないかもしれませんが、それは問題ではありません。

答え1

複数の-eを評価または構成する必要はありません。 Sedはファイルまたはパイプから「プログラム」を読み取ることができ、実際にはsedでもその「プログラム」を生成できます。

cut -f2,4 -d\; usernames.csv \
    | sed -e 's/^/s%ri:username=/' -e 's/;/%ri:username=/' -e 's/$/%/' \
    | sed -i~ -f- confluence/entities_converted.xml

生成されたプログラムを確認するには、最後の行を削除してください。

変更する必要のない行をスキップするには(作業を高速化するため)、sedの間にgrep次のものを挿入して削除します。

   | grep -v '"\(.*\)".*"\1"' \

答え2

awkを使用してusernames.csv(フィールド2と4が異なる)を解析し、sedファイルを生成する必要があります。

 tr -d \" username.csv |
 awk -F\; '$2 != $4 { printf "s/^(.*ri:username=%c)%s(%c.*)$/\\1%s\\2/g\n",34,$2,34,$4 ; }' |
 sed -i -f - confluence/entities_converted.xml

いくつかのヒント

  • 引用符を生成するには、printf "..%c..",34 を使用します。
  • すべてのsed命令が正しく生成されたことを確認するには、デバッグセクションでsed行をスキップできます。
  • /g交換が必要ですか?

私のテストファイルに

;foo;;foo;;
;fubar;;mr X;;
;bar;;bistro;;
    "Full name";"Username";"Email";"New username"
    "Sune Mølgaard";"sune.molgaard";"[email protected]";"smo"

これは

s/^(.*ri:username=")fubar(".*)$/\1mr X\2/g
s/^(.*ri:username=")bar(".*)$/\1bistro\2/g
s/^(.*ri:username=")Username(".*)$/\1New username\2/g
s/^(.*ri:username=")sune.molgaard(".*)$/\1smo\2/g

ユーザー名行を削除しないでください。見つからないと交換できません。

関連情報