より良い説明のために私の質問をしましょう。私は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)ソリューションは、コマンドが別の行に配置されている場合(または少なくとも改行文字が続く場合)、sed
Mac 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