引用符はフィールドを区別しません。

引用符はフィールドを区別しません。

現在、次の種類のテキストに対して操作を実行したいsedコマンドがあります。

user:
        ensure: 'present'
        uid: '666'
        gid: '100'
        home: '/home/example'
        comment: ''
        password_max_age: '99999'
        password_min_age: '0'
        shell: '/bin/false'
        password: ''

次のコマンドを使用して、目的のタイプの結果を取得できます。

sed '/ユーザー:/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tパスワード: \x27\!\!\x27/g'

user:
        ensure: 'present'
        uid: '666'
        gid: '100'
        home: '/home/example'
        comment: ''
        password_max_age: '99999'
        password_min_age: '0'
        shell: '/bin/false'
        password: '!!'

このコマンドの問題はuser:静的です。ユーザーのリストを繰り返し、sedコマンドで特定のユーザーの代わりにbash変数を使用できるようにしたいです。ただし、これを行うには、一重引用符の代わりに二重引用符を使用する必要があります。ただし、このコマンドを使用すると、次のようになります。

sed "/user:/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tパスワード: \x27\!\!\x27/g"

!b私が使用しているsedコマンドで「!」について文句を言います。 (bashがそれを解釈しようとしているので)しかし、次のようにエスケープすると:

sed "/user:/\!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tパスワード: \x27\!\!\x27/g"

これにより、次のエラーが発生します。

sed: -e 式 #1、文字 6: 不明なコマンド: `\'

どのように動作させることができますか?

ベストアンサー1

引用符はフィールドを区別しません。

これはシェル言語の構文では重要ですが、忘れられてしまうという側面です。 「主張引用」事故モデルは実際には単純で間違っています。引用するものは引用し、引用するものは引用しなさい。部分結局、一つの主張になります。

これがあなたがここでしなければならないことです。皮肉なことに、現在削除されている最初の答えは次のとおりです。非常に近い

sed実行の実際の単一引数として提供する最終文字列は次のとおりです。

/user:/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tパスワード: \x27!!\x27/g
このuser部分は実際のユーザー名によって変わります。しかし、ここまで来るには欲しくない完全なパラメータには単一の引用方式が必要です。それぞれの部分で議論をすることができます。

パラメータ拡張が必要な​​部分には二重引用符を使用し、履歴拡張が必要な​​部分には一重引用符を使用します。いいえ起こる:

-riを読むとき
する
   sed -e '/'"$i"':/!b;n;n;n;n;n;n;n;n;n;n;s/.*/\t\tパスワード: \x27! ! \ x27 /g' puppet-users.yaml > puppet-users{new}.yaml
   mv puppet-users{new}.yaml puppet-users.yaml
<user_list.txtを完了してください。

これは:

  1. 一重引用符文字/
  2. 二重引用符文字は、パラメータ$i拡張(もちろん他のすべての拡張と置換も含む)の影響を受けます。
  3. :/!b;n;n;n;n;n;n;n;n;n;s/.*/\t\tpassword: \x27!!\x27/g履歴拡張の影響を受けない一重引用符文字。

フィールド分割は、引用符のない文字でのみ発生します。ここにはそんなことは全くありません。1つのフィールド全体、これすべて議論ですsedコマンドに。

これを行うと、現在実行中のタスクでTAB文字が多すぎていることがわかります。 ☺

手をつないで...

sed作業に適したツールではありません。awk現在削除されている2番目の答えのように、実際にはそうではありません。長期的に現在の作業が少ない場合は、適切なYAMLパーサー(Pythonのyamlモジュールなど)を使用してYAMLを解析することをお勧めします。

このはい作業に適したツールを含む簡単な1行。たとえば、yq使用法は次のようなさまざまなツールです(残念ながらすべてが異なるため)。

-riを読むとき
する
   yq < puppet-users.yaml "$i".password="'\!\!'" > puppet-users{new}.yaml
   mv puppet-users{new}.yaml puppet-users.yaml
<user_list.txtを完了してください。

追加読書

おすすめ記事