4

sed アドレスで簡単な算術演算を行うことは可能ですか? 「アドレス」マニュアルセクションから判断すると、答えはノーのようです。しかし、おそらく回避策はありますか?

たとえば、ファイルの最後から 2 行目を印刷するにはどうすればよいでしょうか。次のようなクールなものになるでしょう:

sed -n '$-1 p' file

しかし、それは明らかに機能しません...そのため、通常、最初に行を識別するために複数の sed 呼び出しを実行し、次にシェル$((expr))を使用して計算を実行し、最後に sed を再度呼び出す必要があります。このような:

sed -n "$(($(sed -n '$ =' file)-1)) p" file

sedアドレスで算術演算を行うための「より良い」、よりコンパクトで読みやすい方法はありますか?


深刻な先延ばしの瞬間に、xterm のカラースキームをすばやく変更する小さなスクリプトを作成することにしました。アイデアは.Xresources、開始マーカーと終了マーカーを含むファイルがあることです。

...
START_MARKER
...
END_MARKER
...

マーカーの間にあるすべてのものを削除したいが、マーカー自体は削除したくない。繰り返しますが、次のようなことを行うのは素晴らしいことです:

sed '/START_MARKER/+1,/END_MARKER/-1 d' file

...しかし、あなたはできません!

4

6 に答える 6

3

そうです、アドレスでさえ、 sed 1で直接数学を行うことはできません。しかし、あなたが望むことをするためにいくつかの策略を使うことができます:

最後から 2 番目の行:

$ seq 5 | sed -n -e '${ # On the last line
> g # Replace the buffer with the hold space
> p # and print it
> }
> h' # All lines, store the current line in the hold space.
4

STARTとの間END:

$ cat test.in
1
START
2
3
END
4
$ cat test.in | sed '/^START$/,/^END$/{
> /^START$/d
> /^END$/d
> p
> }
> d'
2
3
$ cat test.in | sed -n -e '/^START$/,/^END$/!d' -e '/^START/d' -e '/^END$/d' -e p
2
3

BSD (mac) を使用していsedます。;GNU システムでは、改行の代わりに行間で使用できます。または、スクリプトに貼り付けます。

1: Sed はチューリング完全であるため、数学を実行できますが、せいぜい扱いにくいです: http://rosettacode.org/wiki/A%2BB#sed

はい、知っています、UUOC; それは説明のためだけです

于 2012-09-08T21:41:38.347 に答える
1

これはうまくいくかもしれません(GNU sed)。

sed '$!N;$s/.*\n//;P;D' file

これは機能し、理解しやすいはずです。

sed '/start/,/end/!d;//d' file

これらはあなたの質問に対する解決策ですが、算術に関してはawkまたはperlを使用するのが最適です。

于 2012-09-08T22:22:19.077 に答える
1

最後から 2 番目の行を削除します。

sed ':r;$!{N;br};s/\n[^\n]*\(\n[^\n]*\)$/\1/' file

マーカー内のすべてを削除します。

sed ':r;$!{N;br};s/START_MARKER.*END_MARKER/START_MARKER\nEND_MARKER/' file

エレガントではありませんが、ちょっとうまくいきます。

コメントで述べたように、sed行で動作します。ただし、コマンドを使用して別の行をパターン スペースに読み込むことができますN。2 つの線は両方ともパターン スペース内にあり、. で区切られます\nsedまた、実行フロー制御、つまりラベルと条件付き/無条件分岐の手段もあります。すべてが に文書化されています。例を含む完全なリファレンスman sedここにあります。上記のコードにrはラベルがあります。$!{..}「最後の行を除くすべての場所で、do ..;N;br別の行を読み取り、無条件にr再び分岐することを意味します。したがって、すべての入力をパターン空間に読み取り、入力の行を区切っ:r;$!{N;br}て単一の行として操作します。\n

于 2012-09-08T21:13:51.380 に答える
0

いくつかの良いsed提案があります。これは GNU に基づくものですawk:

awk -v RS='START_MARKER|END_MARKER' 'RT == "END_MARKER"' infile
  • RS='START_MARKER|END_MARKER'マーカーをセパレータとして入力を分割します。
  • RT一致したセパレーターに設定され、「END」に一致すると、デフォルトのブロック{print $0}が実行されます。

たとえば、最後の 3 行を除くすべてを印刷する場合は、FS を に設定し\n、適切なループを適用します。

awk -v RS='START_MARKER|END_MARKER' -v FS='\n' 'RT == "END" { for(i=1; i<NF-3; i++) print $i }' infile
于 2012-09-08T22:26:44.503 に答える
-1

簡単な方法を使用して、ファイルの最後から 2 番目の行を表示できます。

TOTAL_LENGTH=$(cat file_name | wc -l)
SECOND_LAST_LINE=`expr $TOTAL_LENGTH - 1`
head -$SECOND_LAST_LINE | tail -1

ファイルから最後から 2 番目の行を削除する場合は、次のようにします。

sed -i "$SECOND_LAST_LINE"d file_name
于 2012-09-08T21:18:55.027 に答える