説明: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」が入力の次の行を読み取ることを確認することでした。また、どの行でも複数の文字列や埋め込み(内部)文字列を変更せずに、行の先頭の#
最初の文字列のみを置き換えました。