時間の経過とともに変更される可能性がある長い文字列から値を抽出しようとしています。たとえば、文字列は次のようになります。
....../filename-1.9.0.3.tar.gz"<....
私が抽出したいのは間の値ですファイル名 -そして.tar.gz、デフォルトではファイルバージョン(この場合は1.9.0.3)です。これが必要なのは、後でコマンドを実行でき、値が1.9.0.6または2.0.0.2であるか、まったく異なる値になる可能性があるためです。
どうすればいいですか?現在はgrepだけを使用していますが、sed、awk、cutなどのような他のユーティリティを使用しても大丈夫です。完全に明確にするには、文字列のファイルバージョン部分を抽出するだけです。かなり長いので(両方とも)、他のすべての部分は何とか削除する必要があります。
答え1
grep -P
/の場合、pcregrep
肯定的な振り返りと肯定的な予測を使用します。
grep -P -o '(?<=STRING1).*?(?=STRING2)' infile
あなたの場合は、次のものSTRING1
と交換してください。filename-
STRING2
\.tar\.gz
アクセス権がない場合、またはサポートされていないpcregrep
場合は、お気に入りのテキスト処理ツールを使用してこれを実行できます。以下は、同じ出力を提供する移植可能な方法です。grep
-P
ed
ed -s infile <<\IN
g/STRING1/s//\
&/g
v/STRING1.*STRING2/d
,s/STRING1//
,s/STRING2.*//
,p
IN
仕組み:各項目に改行文字を追加してSTRING1
(今は各行は最大1回発生します)、STRING1.*STRING2
残りは一致しない行をすべて削除し、間のSTRING1
内容を保持してSTRING2
結果を印刷します。
答え2
POSIXシステムを持っていない人のために、またはPOSIXシステムをgrep -P
使用してこれを行うことができます。sed
awk
sed -n -e 's/^.*\/filename-\([^\/]*\)\.tar\.gz.*$/\1/p' -e T -e q
説明:デフォルトの印刷をオフにして、目的のパターンを含む行を見つけて保持したい部分を除くすべての部分を交換し、交換結果を印刷して一致する場合は終了します。最初の一致行に複数の一致がある場合は、最後の一致が選択されます。
awkを使用(ラインの最初の項目を選択):
awk 'match($0, /filename-[^/]*\.tar\.gz/) {
print substr(RSTART + 9, RSTART + RLENGTH - 9 - 6, $0);
exit;
}'