sedまたはawkを介して3行グループの最初、3行、5行目を抽出する方法は?

sedまたはawkを介して3行グループの最初、3行、5行目を抽出する方法は?

ファイルがあるとしましょう。

Line1
Line2
Line3
Line4
Line5 
Line6
Line7 
Line8 
Line9
Line10
Line11
Line12

私は欲しい:

Line1
Line2
Line3
Line7 
Line8 
Line9
Line13
Line14
Line15

つまり、3行(含む)の奇数が欲しいのです。

私はいくつかのアイデアを持っています:for (i=1, i<=FR, i+5), {sed -n,'i, i+1p' } < input

sedのforループ構造を教えてもらえますか?この問題を解決するには?

答え1

この試み

awk 'NR % 6 == 1 || NR % 6 == 2 || NR % 6 == 3' filename.txt > output.txt

答え2

seq 20|
sed 'n;n;n;$!N;$!N;d'

n現在の行を追加の入力行で上書きし、nそれが含むパターンスペースを印刷します。(そうしないsed -n限りsed -e'#n'だから私たちはこれを3回実行し、2つの追加入力ラインをバッファリングし、d多くを削除します。

1
2
3
7
8
9
13
14
15
19
20

私が持っているもう一つのことはこれです:

sed -ne:p -e'$p;N;s/\n/&/2p;tn' -ebp \
     -e:n -en \
     -e:d -e'N;s/\n/&/2;t'      -ebd

Nまず、2つの追加の外部入力ラインをバッファリングし、追加された\newlineを計算し、現在のラインが最後のラインであるかバッファがいっぱいになったかを印刷し、そのラインを削除する前にそのラインを外部入力ラインで上書きしますn。 2行をさらにバッファリングします。

次のように書くこともできます。

sed -ne:p -e'$p;N;s/\n/&/2p;tn' \
     -ebp -e:n -e'n;n;n'

しかし、estsの利点tは、次のように簡単にパラメータ化できることです。

altl(){ sed -ne":t$(n=0 nt='\n\t' b=$nt\b
        while   [ "$#" -gt "$((!(n+=1)))" ]  &&
                c=${1%?}        p=${1##*[!p]} \
                l=$nt${p:+\$p;} p=$nt$p${p:+;}n
        do      case    $1      in
                (''|0*|*[!0-9]*?|*[!pd])
                   >&2  printf '"%s":\tARG ERR\n' "$1"
                        kill -2 0;;
                (1?|?|$((c-=1))) ! :; esac         &&
                printf  "\n:$n.0${l}N;%s$c;t$n.1%b" \
                        's/\n/&/' "$b$n.0\n:$n.1"
                shift;  printf %b "$p${1+\c}${nt}bt"
        done)"
}

実際、他のものを作ることも特に難しくありません。一度にあまりにも多くを印刷するだけ[Nn]ですsed。だから、おそらく私は上記の文章を書くのに時間を無駄にしていたでしょう。しかし、動作します。

(   set -x
    seq 150 |
    altl p 40d p p 10d 5p
)

### This is the sed script the function's shell loop writes.
### We see it because I enabled -xtrace output on stderr.

:t
    p;n
:2.0
    N;s/\n/&/39;t2.1
    b2.0
:2.1
    n
    p;n
    p;n
:5.0
    N;s/\n/&/9;t5.1
    b5.0
:5.1
    n
:6.0
    $p;N;s/\n/&/4;t6.1
    b6.0
:6.1
    p;n
    bt

### This ends the sed script.
### The rest is sed's stdout.

1
42
43
54
55
56
57
58
59
100
101
112
113
114
115
116
117

関連情報