次に始まる最初の行を見つけます。次のような

次に始まる最初の行を見つけます。次のような

より良い説明のために私の質問をしましょう。私はcygwinを使用しており、インストールは次のsetup.ini形式に基づいています。

    @ package-name
    sdesc: "short description, on one line"
    ldesc: "long description of arbitrary length, commonly multiple lines"
    category: categories in which the packege belonges, one line
    requires: packages (libs etc) required by this package, one line

その後、以下のパッケージなどがあります。

必要なのは、パッケージ名が与えられたら、そのパッケージに必要なすべてのパッケージを出力することです(可能な場合は「requires」プレフィックスなし)。

私はこれが基本的なgrepであると確信していますが、最初に触れました。ありがとうございます。

答え1

このタスクを実行するためにgrepをどのように使用するかはわかりませんが、このタイプのタスクにはawkを好みます。それは私がやりたいことをよりよく制御することを可能にします。私はawkの専門家ではありませんが、まだ学んでいますが、これを達成した方法は次のとおりです。

PKGNAM="package-name"; awk "/$PKGNAM\$/,/requires:/ { if ( \$0 ~ /requires:/ ) { sub( /^requires:.?/, \"\"  ); print } }"

修正する:PKGNAM変数を使用して、パッケージ名と一致するようにawkコマンドの例を更新しました。

ここに画像の説明を入力してください。

HTH。

答え2

Grepはすべての行を独立して処理するため、単独で操作を実行することはできません。

awkは一般的なテキスト処理ツールです。現在のパッケージが何であるか(変数で)追跡し、正しいパッケージで行が見つかった場合はp一致を出力します(接頭辞が削除されます)。requires:requires:

<setup.ini awk -vpackage='NAME_OF_PACKAGE' '
    sub(/^@ */,"") {p=$0}
    p==package && sub(/^requires: */,"") {print}
'

@別のawkアプローチは、改行ではなく一連の改行で区切られた入力を処理することです。あるいは、パッケージセクションの間に空行があるため、段落ごとに入力を処理するには、空の文字列をレコード区切り文字として渡しますRS(これは、レコードが1つ以上の空行に区切られていることを意味します)。その後、目的のレコードの各行に対して行が始まる場合にrequires:印刷します(プレフィックス減算)。

<setup.ini awk -vpackage='NAME_OF_PACKAGE' -vRS= -vFS='\n' '
    sub(/^@ */,"") && $1==package {
        for (i=2; i<NF; i++) {if (sub(/^requires: */,"",$i)) print $i}
    }'

もう1つの可能性はPerlの短絡モード(-00)です。段落は右側のヘッダー(/REGEXP/m複数行の一致を表すため、$アンカーは文字列の終わりではなく行の終わりを表します)で始まり、lineを含む場合はrequires:その行を印刷します(接頭辞を減算)。

<setup.ini package=NAME_OF_PACKAGE perl -00 -ne '
    /\A@ *$ENV{package}$/m and /^requires: *(.*)$/m and print "$1\n"'

これは(GNU) sed愛好家のためのものです。 (これを理解してはいけません。)

sed -ne '/^@/ { h; b; }; G; s/^requires: *\(.*\)\n@ *NAME_OF_PACKAGE$/\1/p'

答え3

sed逆参照なしにこれを行うソリューションは次のとおりです。

# cf. "3.3. Addressing and address ranges",
# http://sed.sourceforge.net/sedfaq3.html#s3.3 (esp. (6) Relentless. ...)

PKGNAME="package-name"
sed -ne '/^ *@ *'"${PKGNAME}"'/{
:a
N
/\n *requires: /!ba
s/.*\n *requires: *//
p
}' setup.ini 

Gilles(GNU)ソリューションは、コマンドが別の行に配置されている場合(または少なくとも改行文字が続く場合)、sedMac OS X 10.6.7(FreeBSD sedを使用)で動作します。b

PKGNAME="package-name"
sed -ne '/^ *@ *'"${PKGNAME}"'/{h
b
};G;s/^ *requires: *\(.*\)\n *@ *'"${PKGNAME}"' *$/\1/p' setup.ini

関連情報