ループで印刷すると、二重バックスラッシュが消えます。

ループで印刷すると、二重バックスラッシュが消えます。

さまざまなデータフィールドのリストを一緒にリンクし、さらに列を追加する必要があるスクリプトがあります。生成されたファイルは次のとおりです。

$ cat compiled.csv
"name":"Network Rule 1", "description":"Network Rule 1", "from":["internal"], "source":["any"], "user":["domain\\network_user1"], "to":["external"], "destination":["host.example.com","10.1.2.1"], "port":["8443","22"],
"name":"Network Rule 2", "description":"Network Rule 2", "from":["internal"], "source":["any"], "user":["domain\\network_user2"], "to":["external"], "destination":["host.example.com","10.2.1.1"], "port":["23","25"],
"name":"Network Rule 3", "description":"Network Rule 3", "from":["internal"], "source":["any"], "user":["domain\\network_user3"], "to":["external"], "destination":["host.example.com","10.3.4.1"], "port":["80","143"],

リストに追加のフィールド(すべて同じ)を追加しようとしています。フィールドは次のとおりです。

「接続」:「許可」、「時間」:「00:00:00-23:59:59」、「通知」:「はい」

最終出力は次のようになります。

"name":"Network Rule 1", "description":"Network Rule 1", "from":["internal"], "source":["any"], "user":["domain\\network_user1"], "to":["external"], "destination":["host.example.com","10.1.2.1"], "port":["8443","22"], "access":"allow", "time":"00:00:00-23:59:59", "notify":"yes"
"name":"Network Rule 2", "description":"Network Rule 2", "from":["internal"], "source":["any"], "user":["domain\\network_user2"], "to":["external"], "destination":["host.example.com","10.2.1.1"], "port":["23","25"], "access":"allow", "time":"00:00:00-23:59:59", "notify":"yes"
"name":"Network Rule 3", "description":"Network Rule 3", "from":["internal"], "source":["any"], "user":["domain\\network_user3"], "to":["external"], "destination":["host.example.com","10.3.4.1"], "port":["80","143"], "access":"allow", "time":"00:00:00-23:59:59", "notify":"yes"

スクリプトとシェルから直接次のコマンドを実行したときにループにフィールドを追加しようとすると、デュアルバックスラッシュが消えます。

while read LINE; do
 echo $LINE \"access\":\"allow\", \"time\":\"00:00:00-23:59:59\", \"notify\":\"yes\"
done < compiled.csv > completed_list.csv

代わりに、次の例では、ユーザー名の二重バックスラッシュが消えます。

"name":"ネットワーク ルール 1", "説明":"ネットワーク ルール 1", "from":["internal"], "source":["any"],"ユーザー": ["ドメイン\ネットワーク_ユーザー1"]、 "ターゲット":["外部"], "ターゲット":["host.example.com","10.1.2.1"], "ポート":["8443","22"], "アクセス":"許可"、"時間":"00:00:00-23:59:59"、"通知":"はい"

echoを使用して行全体を印刷するのに問題があるようですが、この問題を解決する方法はありますか?

よろしくお願いします。

答え1

readデフォルトでは、区切り文字でIFS文字をエスケープするために使用できるバックスラッシュが解釈されます。この-rオプションはこれをオフにします。

$ read a b  <<< '1\ 2 3'
$ printf "<%s>\n" "$a"
<1 2>
$ read -r a b  <<< '1\ 2 3'
$ printf "<%s>\n" "$a"
<1\>

また、変数名のみを指定しても、先行スペースと末尾のスペースread(IFSにある場合)が削除されるため、変更されていない入力行を取得するには、IFSを空の文字列に明示的に設定する必要があります。

シェルと設定によっては、次のことがechoできます。返品印刷時にバックスラッシュを処理します。を使用する方が良いですprintf "%s\n" "..."

また、二重引用符を印刷する場合は、各文字列を個別にエスケープするよりも、単一引用符で文字列全体を引用する方が簡単になる可能性があります。

おそらく:

while IFS= read -r LINE; do
    echo "$LINE"' "access":"allow", "time":"00:00:00-23:59:59", "notify":"yes"'
done < compiled.csv > completed_list.csv

その後、各行の最後に固定文字列を追加するように見えるので、代わりにsedを使用できます。シェルよりも速いかもしれません。

sed -e 's/$/ "access":"allow", "time":"00:00:00-23:59:59", "notify":"yes"/' < compiled.csv > completed_list.csv

関連情報