sed 魔法が必要です。表示された行をファイルの先頭に移動します。

sed 魔法が必要です。表示された行をファイルの先頭に移動します。

私は魔法が切実に必要であることに気づきましたsed本物私は座ってこれを学ばなければならない)。行が多いファイルがあります。レビュー後、行の先頭にアスタリスク(*)を追加していくつかの行を表示しました。

(可能であれば)私がやりたいいくつかのトリックは、sedすべてのマーカーラインをファイルの先頭(または最後 - トリッキーではない)に移動してブロックを形成することです。表示されていない他の線は邪魔にならないでください。

どうすればこれを行うことができますかsedsedテキストを移動するためのバッファがあることを知っています。

答え1

sedが必要ですか?ソースファイルを2回見るのが大丈夫なら、grepを使って簡単に実行できます。

例えば

grep '^\*' input > outputfile
grep -v '^\*' input >> outputfile

答え2

ファイルサイズに応じて、次のことができます。

sed '/^*/!H;//p;$!d;g;s/\n//'

H一致しない古い空間ラインに積み上げられています/^*/。対応する一致は、p入力に表示されるとおりに印刷されます。その後、!最後の行以外のすべての行が出力から削除されます$d最後の行では、gパターンスペースを上書きしてスペースを保存し、最初の行は毎回追加の文字を生成するため、最初の\newline文字が置き換えられます。s/\n//H

Hただし、これはすでにすべての行を以前のスペースに格納しているため、大きなバッファが必要です。一方、これは...

sed '/^*/p;$!d;g;r file' <file    |
sed -e '1,/^$/{/./p;d' -e '};/^*/d'

...そのような要件はありません。

最初は最後の行まで一致する行だけをsed p印刷し、最後の行では空の行を印刷してから、入力ファイル全体を再読み込みします。/^*/$r

2番目はsed最初の行から最初の空行までの行の範囲内で動作し、少なくとも1文字に一致するpすべての行を印刷してからバッチをd削除します。最初の空白行に出会った後、d一致するすべての行を削除します/^*/

答え3

これを行う必要はなく、sedデフォルトのgrepを使用してアスタリスク(*)行を一番上にドラッグできます。次のファイルがあるとしましょう。

$ cat sample.txt 
1
2
3
4
* 5
* 6
* 7
8
9
10

次に、grep古いexample.txtファイルにアスタリスク(*)行を追加します。

$ cat <(grep '*' sample.txt) <(grep -v '*' sample.txt)
* 5
* 6
* 7
1
2
3
4
8
9
10

上記のコマンドは2つのgrepを実行します。最初のコマンドはアスタリスクのあるすべての行を取り出し、2番目のコマンドはアスタリスク以外のすべての行を取得します。これら2つのコマンドの出力は、コマンドへの入力としてシンボリックリダイレクトをcat使用します。<()

代替方法

cat + 2サブシェルを使用したくない場合は、@terdonが提案したように実行できます。

$ grep '*' sample.txt; grep -v '*' sample.txt

sample.txtこれにより、アスタリスク(*)を含むすべての行が抽出され、その後にアスタリスク(*)が含まれていないすべての行が表示されます。

引用する

答え4

2つのブロックの間に空白行があっても大丈夫なら:

sed -n -e '/^* /{H;$!d}' -e '/^* /!p' -e '${g;p}'

あるいはその逆に

sed -n -e '/^* /{p;$!d}' -e '/^* /!H' -e '${g;p}' file    

関連情報