別の文字列の後に#で始まる文字列を前の行に移動できますか?

別の文字列の後に#で始まる文字列を前の行に移動できますか?

次のスクリプトファイルがあります。

auditctl -a always,exit -F arch=b64 -S openat -F auid=1000      <TAB> #description of command....
auditctl -a ....                                                <TAB> #long description

(コメントの前のタブ文字に注意してください。)

、またはsed内部コマンドを使用して文字列自体の後に説明を入れることができるため、次のような結果が表示されます。awkvim#

#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000      


#long description
auditctl -a ....

このコマンドを試しましたが、norm結果は災害でした。

:'<,'>norm f#D O P

答え1

match()GNU awkを3番目の引数と\S/\s略語として使用します。

$ awk 'match($0,/([^#]*\S)\s*(#.*)/,a) { $0=a[2] ORS a[1] } 1' file
#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description
auditctl -a ....

または、POSIX awkを使用してください。

$ awk 'match($0,/[[:space:]]*#/) { $0=substr($0,RSTART+RLENGTH-1) ORS substr($0,1,RSTART-1) } 1' file
#description of # command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description
auditctl -a ....

上記の#コードは、コメントに含まれる文字(aを含む)とコメントの前にスペースがあるかどうかにかかわらず機能し、印刷する前に残りの行の末尾からコメント前のスペースを削除します。

答え2

を使用すると、sed逆参照を使用してパターンを一致させることができます。

sed 's/\(PATTERN1\)\(PATTERN2\)/\2\n\1/'

2つのパターンを反転し、それらの間に改行文字を追加します。たとえば、PATTERN1は行^.*の先頭から始まる任意の文字、PATTERN2は行の#.*$終わりまでの任意の数の文字が続くハッシュ記号です。

余分なスペースを削除するには、以下を追加する必要があります。

's/ *$//'

#一致の最初の部分で文字(つまり、NOT以外のすべての文字)を除いて、[^#]自分のテキストからコメントを処理するのも良い考えです#。組み合わせると次のようになります。

sed 's/\(^[^#]*\)\(#.*$\)/\2\n\1/;s/ *$//'

答え3

次のawkプログラムは、次のことを行う必要があります。

awk '/^ *[^ #].+#/{n=index($0,"#"); print substr($0,n); $0=substr($0,1,n-1)}1' input.sh

これにより、次のことが行われます。

  • 最初の文字(おそらく先行スペースの後ろ)がある行のみを処理することを確認します。いいえ記号#、つまり「通常のコメント」行ではなく、コマンドの後のコメントであることを確認してください。
  • このような行にある場合は、最初の行の位置を決定して#に保存しますn。次に、その位置から始めて、現在の行の部分文字列を別の行に印刷します。次に、現在の行を#。このアプローチは、#コメントセクション自体にその文字が含まれている場合も処理します。
  • 1すべての行に対して変更された可能性がある内容を含む印刷します(これはルールブロックの外側に「欠けている」と表示されます)。

awkファイルの内部編集は行われないため、出力を一時ファイルにリダイレクトする必要があります。または、GNU Awk 4.1.0以降がある場合は、-i inplaceこの拡張を真の内部編集に使用できます。

答え4

rev@ Ed Mortonが指摘した代替ケースのようなこのアプローチは気に入っています。

入力ファイルの例:

auditctl -a always,exit -F arch=b64 -S openat -F auid=1000      #description of command....
auditctl -a ....                                                #long description
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000#description of command....
auditctl -a ....                                                #long description# foo
auditctl -a ....                                                # long description#foo
$ rev file | sed 's/^\(.*\)#[[:blank:]]*/\1#\n/' | rev
#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description
auditctl -a ....
#description of command....
auditctl -a always,exit -F arch=b64 -S openat -F auid=1000
#long description# foo
auditctl -a ....
# long description#foo
auditctl -a ....

関連情報