パターンに基づいて行を削除しますが、最初のn個の一致する行は保持します。

パターンに基づいて行を削除しますが、最初のn個の一致する行は保持します。

パターンに基づいてテキストファイルから行を削除する必要がありますが、最初のn行はパターンと一致するようにしてください。

入力する

% 1 
% 2
% 3
% 4
% 5
text1
text2
text3

出力

%1
%2
text1
text2
text3

ファイルを使用しましたが、sed /^%/d%で始まるすべての行を削除しましたが、sed 3,/^%/dそれも機能しませんでした。パターンの最初のn行を維持し、残りは削除する必要があります。

答え1

%put で始まるすべての行を削除し、最初の 2 行の入力を保持するには、次のようにします。

sed -e 1,2b -e '/^%/d'

以下を使用する方が明確ですがawk

awk 'NR <= 2 || !/^%/'

または公演を終えた後の場合:

{ head -n 2; grep -v '^%'; } < input-file

入力の最初の行ではない可能性がある最初の2行をパターンと一致させるには、次の方がawk確かに良いオプションです。

awk '!/^%/ || ++n <= 2'

を使用するには、sed次の技術を使用できます。

sed -e '/^%/!b' -e 'x;/xx/{h;d;}' -e 's/^/x/;x'

すなわち、予約された空間を用いて、現在まで一致するパターンの発生回数を数える。効率的ではなく、明確ではありません。

答え2

これを単独で行うには簡単すぎるようですsed(不可能ではありませんが、やや複雑です。sedプッシュボックス何ができるか)。

どうですかawk

#!/bin/awk -f
BEGIN { c = 0; }
{
    if (/^%/) {
        if (c++ < 3) {
            print;
        }
    } else {
        print;
    }
}

最新のBASH(正規表現サポート)が利用可能な場合は、上記のawkを次のように翻訳できます。

#!/bin/bash -
c=0
while IFS= read -r line; do
    if [[ $line =~ ^% ]]; then
        if ((c++ < 3)); then
            printf '%s\n' "$line"
        fi
    else
        printf '%s\n' "$line"
    fi
done

パターンマッチングのために演算子の代わりにsedまたはを使用することもできます。grep=~

答え3

真珠一行解決策:

# in-place editing
perl -i -pe '$.>2 && s/^%.*//s' filename.txt

# print to the standard output
perl -ne '$.>2 && /^%/ || print' filename.txt

答え4

sed '/^%/{
3,$d}' '% 1 
% 2
% 3
% 4
% 5
text1
text2
text3'

不要な線を削除する方法です。

編集:私の答えはsと同じ条件で機能し、Stephane Chazelas%行が最初に出なければ機能しません。


ナード狙撃。

sed -n '/^% [^12]*$/!{
/^% [12][[:digit:]]\{1,\}/n
p}' file.txt

% numberこれは、ストリーム内の文字列が見つかる場所に関係なく機能します。%またはそれ以外の文字数で始まり終わる行は無効になります。住所は死角を除いてすべて一致しました。 10〜29の間の数字は印刷され続けます。したがって、範囲に一致するように2番目のアドレスを入れ子にして行をスキップします。12/% [A-Za-z3-9]*/

しかし、それでもまだ良いでしょう。

関連情報