テキストファイルから単一範囲の行をコピーする方法を見つけようとしています。範囲はファイルの一意の行で始まりますが、ファイル内の複数の場所に存在できる行で終わります。
以下は、処理する必要があるいくつかの入力例です。
想像力がない したがって、このサンプルテキストは 一般的な 退屈だ。しかし、それは本当です。 質問を表示 私はそれに取り組んでいます。 一般的な こんにちはお母さん! ユニークなラインです。 もっと コピーするテキスト しかも。 一般的な 後ろに文字が来る コピーされませんでした。
コピーして編集する必要がある行は、ここに表示するために太字で表示されています。
私が必要とする出力は次のとおりです
想像力がない したがって、このサンプルテキストは 一般的な 退屈だ。しかし、それは本当です。 質問を表示 私はそれに取り組んでいます。 一般的な こんにちはお母さん! 変わるラインです。 そしてここでははるかに違います。 コピーするテキスト しかも。 一般的な ユニークなラインです。 もっと コピーするテキスト しかも。 一般的な 後ろに文字が来る コピーされませんでした。
明確にするために、追加の出力は太字で表示されます。
次に始まる行の範囲を取得する必要があります。
ユニークなラインです。
次の行で終わります。
一般的な
この範囲の行は、元の範囲の行の前に挿入する必要があります。行の範囲に一致するコピーを少し変更する必要があります。
範囲を終了する「共通」行自体がファイル内の複数の場所に表示されることがあります。
私は動作するスクリプトを思い出しましたが、awk
必要なものよりはるかに複雑に見えます。私のawk
技術は単に存在しませんでした。
/This is a unique line/{flag=1}
/Common/{
if (flag > 0) {
n=m;
sub("some","different",n);
sub("unique","changed",n);
print n "\n" $0 "\n" m;
m=""
};
flag=0
};
flag{
if (length(m) > 0) {
m=m "\n" $0
} else {
m=$0
}
}
!flag{ print }
これを達成するためのよりクリーンで簡潔な方法はありますか?その他のオプションも開いていますawk
。 macOSで利用可能な標準コマンドです。
答え1
使用ex
、POSIX指定ファイルエディタ(非視覚的形態も同様vi
)。
printf '%s\n' '/This is a unique line' '.,/Common/copy -' %p | ex file.txt
これにより、変更されたファイルの内容が印刷されますが、変更は保存されません。
変更を保存するコマンドは次のとおりです。
printf '%s\n' '/This is a unique line' '.,/Common/copy -' x | ex file.txt
AwkやSedとは異なり、ex
行を順次修正することに限定されない。代わりに、単に前進するのではなく、バッファ全体で動作します。
最初のコマンド/This is a unique line
は単にモーションコマンドです。がある場所にカーソルを移動しますThis is a unique line
。
次のコマンドはcopy
コマンドです。現在の行(.
)から一致する次の行までのアドレス範囲で機能し、Common
それを-
現在の行()の前の行にコピーします。
更新:変更後にコピーのために最初に始まる行を表示します。コピーする最初の行には「b」というラベルが付けられ、その前の行には「a」というラベルが付けられます。コピーされた行は 'aと'bの間に配置され、この行をアドレスの「置換」コマンドとして使用できます。ところで、Andt
は同義語です。copy
printf "/Here is a unique line
kb
-ka
.,/Common/t 'a
'a+,'b-s/unique/changed/g
'a+,'b-s/some/different/g
x
" | ex file.txt
答え2
sed -e '
/This is a unique line/,/Common/!b
H
/Common/!d
g
s/^\n//
h
s/unique/changed/
s/some/different/
G
' yourfile
説明する
- まず、範囲ではなく行を拒否します。
- 範囲内の各行の予約済みスペースに追加します。
- 共通行が表示されるまで読み取ったすべての行を削除します。この時点で、予約済み領域(全範囲+先行する「\ n」を含める必要があります)を検索します。
- この先行改行文字を削除し、保存を更新します。これは
H
BTWコマンドによるものです。 - 今すぐ編集に移動します。一意性 - >変更、一部 - >相違、...
- 予約済みスペース(変更されていないバージョン)をパターンスペース(変更されたバージョン)に追加します。
- sed はパターン空間の内容を自動的に印刷します。
答え3
awk '/This is a unique line/,/Common/{
H = H RS $0
if ( $0 ~ /Common/ ) {
g = H
sub("\n","",g)
sub("some","different",g)
sub("unique","changed",g)
$0 = g H
} else { next }
}1' inputfile
これはsed
に翻訳されますawk
。
awk
持っているコードは、行を追跡するために変数フラグをオンまたはオフにする役割を果たします。ただし、演算子を使用すると、後でawk
同じことがすでに実行されます。range
,