説明:GNU sedを使用してください。
現状 - ~/.screenrc、最後の数行:
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
# name thrashmetal
# screen -t script emacs -nw /home/$USER/bin/thrashmetal
# number 1
# split -v
# focus
# chdir "/home/$USER/thrashmetal/src"
# screen -t scr watch nl asdkjlek.html
# number 2
# focus
# split
# focus
# screen -t output watch thrashmetal asdkjlek.html
# number 3
# focus
# split
# focus
# chdir "/home/$USER/thrashmetal/plan"
# screen -t soll watch less soll
# number 4
# focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave
目的:
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
name thrashmetal
screen -t script emacs -nw /home/$USER/bin/thrashmetal
number 1
split -v
focus
chdir "/home/$USER/thrashmetal/src"
screen -t scr watch nl asdkjlek.html
number 2
focus
split
focus
screen -t output watch thrashmetal asdkjlek.html
number 3
focus
split
focus
chdir "/home/$USER/thrashmetal/plan"
screen -t soll watch less soll
number 4
focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave
現在の試みはほとんど成功しましたが、次の行が表示されたら停止しません。この行は、コメント記号や英数字のない新しい行です。
sed 's+^# \(name thrashmetal\)+\1+;:a;s+# ++;ta' .screenrc
説明、意図:
'
一連のやるべきことの始まりs
変える+
「+」を区切り文字として使用してください。# …
「#」で始まる行が見つかるまで1行ずつ見てください。\(
後で参照できるようにグループを開始name thrashmetal
そして「スラッシュメタル名」で続けてください。\)
グループの終わり+\1+
行の最初の項目を「#」なしでグループ部分に置き換えます。;
そしてその時点から別のことをしてください...:a
「a」というループを作ります。;s
各後続の行ごとに1行ずつ交換してください。+
「+」を区切り記号に設定#
行の後に続く内容に関係なく、行に「#」が最初に表示される場合...++
何もありません。効果的に削除してください。;ta
失敗したら、段落の終わりに達すると、スラッシュメタルブロックとダークウェーブブロックを区切る2行が壊れます。、次に「a」の位置に戻ります。'
一連のやり方が終わりました。.screenrc
現在のディレクトリ(マイホームディレクトリ)にある「.screenrc」ファイルに対して一連の操作を実行します。
標準出力:
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
name thrashmetal
screen -t script emacs -nw /home/$USER/bin/thrashmetal
number 1
split -v
focus
chdir "/home/$USER/thrashmetal/src"
screen -t scr watch nl asdkjlek.html
number 2
focus
split
focus
screen -t output watch thrashmetal asdkjlek.html
number 3
focus
split
focus
chdir "/home/$USER/thrashmetal/plan"
screen -t soll watch less soll
number 4
focus
name darkwave
screen -t script emacs -nw /home/$USER/bin/darkwave
この問題を解決するには?スラッシュメタル段落の終わりに達するとすぐにループが止まらず、単に次の段落(darkwave段落)にジャンプして続くようにするには、私が何を間違っているのでしょうか?
私の考えでは、そのループにあるものは何でも間違っていると思います...おそらく「t」かもしれませんが、「T」や「b」も切り捨てられません...
答え1
sed '/^# name thrashmetal$/,/^$/ s/^# //' file
#
これにより、範囲内の各行から最初と後続の空白文字が削除され、置換が適用されます。
範囲は行一致で始まり^# name thrashmetal$
、最初の後続の行一致^$
(空行)で終わります。
または次に直接翻訳されますawk
。
awk '/^# name thrashmetal$/,/^$/ { sub(/^# /, "") }; 1' file
ここで、末尾は、1
または{ print $0 }
の省略形{ print }
として現在の(修正可能な)行が出力されるようにします(テキスト印刷はsed
スクリプトに暗黙的に適用されます)。
編集者に興味がある人は、ed
次の編集コマンドを使用してこの問題を解決できます。
/^# name thrashmetal$/;.,/^$/ s/^# //
これにより、カーソルが目的の段落の最初の行に移動し、空の行に達するまで、その行とすべての後続の行に代替が適用されます。
私たちは使用できません
/^# name thrashmetal$/,/^$/ s/^# //
...アドレスは現在の行に基づいて計算され、現在の行はエディタの起動時にファイルの末尾にあるためです。ファイルの末尾にあるため、アドレスが/^$/
開始アドレスよりも前の行になるため、コマンドの範囲は何の影響もありません。 (最初の空白行は現在の行に基づいて段落の先頭の前にあります。)
独自の方法が修正されました(区切り記号をプラス記号からデフォルト値に変更し、複数の式に分割することで移植性が高くなります)。
sed -e '/^# \(name thrashmetal\)/!b' -e 's//\1/' -e :a -e n -e 's/^# //' -e ta file
最初の置換を実行する代わりに、段落の最初の行の一致によって、残りの編集スクリプトをスキップするかどうかが決まります。b
その行が見つからない場合はスキップします。
行が見つかったら、それを修正してラベルを作成しますa
。次に現在のバッファを印刷し、その内容を次の行に置き換えますn
。ループは以前と同様に続き、#
バッファの内容が変更されると部分文字列を削除してラベルにループし直します。
最初の試みの主な問題は次のとおりです。
sed 's+^# \(name thrashmetal\)+\1+;:a;s+# ++;ta' .screenrc
... " a
-loop"は無条件であるため、最初の置換が成功したかどうかに関係なく、入力されたすべての行に適用されます(最初の2行はコマンドの影響を受けませんが、コピー/貼り付けエラーのようです)。 。ループは次の行も読みませんので、単に実行されます。一度1行あたり(#
1行に複数の部分文字列が見つからない限り)
私の修正は、最初の交換をテストと交換に分割し、交換がa
失敗するまで「-loop」が入力の次の行を読み取ることを確認することでした。また、どの行でも複数の文字列や埋め込み(内部)文字列を変更せずに、行の先頭の#
最初の文字列のみを置き換えました。
答え2
このスクリプトはあなたが望むことをするようです。
H
/^$/ T show
$ T show
d
:show
x
s/\n//
/^# name thrashmetal/ {
s/# //
s/\n# /\n/g
}
私たちは効果的に空白の線で区切られた塊に物を分割します。で始まるブロックが見つかったら、lineで始まるすべての文字列を# name thrashmetal
削除します#
。
入力例が与えられると、出力が生成されます。
$ sed -f filter.sed < example.conf
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
name thrashmetal
screen -t script emacs -nw /home/$USER/bin/thrashmetal
number 1
split -v
focus
chdir "/home/$USER/thrashmetal/src"
screen -t scr watch nl asdkjlek.html
number 2
focus
split
focus
screen -t output watch thrashmetal asdkjlek.html
number 3
focus
split
focus
chdir "/home/$USER/thrashmetal/plan"
screen -t soll watch less soll
number 4
focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave
コメント付きの sed スクリプト:
# Append current line to the hold space
H
# If we find a blank line or reach EOF, print out the
# current chunk
/^$/ T show
$ T show
# Delete the current line (we'll print it later in the
# show routine)
d
:show
# Swap the pattern space and the hold space
x
# Remove the initial "\n" that was added when we appended
# the first line with the H command
s/\n//
# If this is our target chunk, remove the comments
/^# name thrashmetal/ {
s/# //
s/\n# /\n/g
}
答え3
awkの使用を検討することもできます。
$ awk -v RS= -v ORS='\n\n' '/thrashmetal/{sub(/^# /,"");gsub(/\n# /,"\n",$0)}1' .screenrc
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
name thrashmetal
screen -t script emacs -nw /home/$USER/bin/thrashmetal
number 1
split -v
focus
chdir "/home/$USER/thrashmetal/src"
screen -t scr watch nl asdkjlek.html
number 2
focus
split
focus
screen -t output watch thrashmetal asdkjlek.html
number 3
focus
split
focus
chdir "/home/$USER/thrashmetal/plan"
screen -t soll watch less soll
number 4
focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave
ここで、RS(Input Record Separator)を空白に設定することで、段落を単一行として扱うことができます。
答え4
使用幸せ(以前のPerl_6)
~$ raku -ne 'if / thrashmetal /fff^/ \# \s name / { .subst(/^ "\# " /).put } else { $_.put };' file
または:
~$ raku -ne 'put (/ thrashmetal /fff^/ \# \s name /) ?? $_.subst(/^ "\# " /) !! $_ ;' file
RakuはPerlファミリーのプログラミング言語です。 Raku-ne
のawkに似た非自動印刷コマンドラインフラグとif / elseステートメントを使用して、選択した行を変更できます。
ここで重要なのは、/…ON…/fffˆ/…OFF…/
最初の認識フィールドが一致するとONに変わり、2番目の認識フィールドが一致するとOFFに変わるRakuの「トリガー」演算子を使用することです。これに基づいて、fff
ここに末尾の^
キャレットを追加して、Rakuに2番目の一致行を削除するように指示します。
thrashmetal
したがって、最初の一致と\# \s name
2番目の一致の両方に必要なコメント付きレコード/段落を一度に一致させることができます。識別されたレコードのコメント解除を使用してください.subst(/^ "\# " /)
。
入力例:
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
# name thrashmetal
# screen -t script emacs -nw /home/$USER/bin/thrashmetal
# number 1
# split -v
# focus
# chdir "/home/$USER/thrashmetal/src"
# screen -t scr watch nl asdkjlek.html
# number 2
# focus
# split
# focus
# screen -t output watch thrashmetal asdkjlek.html
# number 3
# focus
# split
# focus
# chdir "/home/$USER/thrashmetal/plan"
# screen -t soll watch less soll
# number 4
# focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave
出力例:
# name synthpop
# screen -t script emacs -nw /home/$USER/bin/synthpop
name thrashmetal
screen -t script emacs -nw /home/$USER/bin/thrashmetal
number 1
split -v
focus
chdir "/home/$USER/thrashmetal/src"
screen -t scr watch nl asdkjlek.html
number 2
focus
split
focus
screen -t output watch thrashmetal asdkjlek.html
number 3
focus
split
focus
chdir "/home/$USER/thrashmetal/plan"
screen -t soll watch less soll
number 4
focus
# name darkwave
# screen -t script emacs -nw /home/$USER/bin/darkwave