web-dev-qa-db-ja.com

2つの異なる一致の間のテキストを抽出する

特定の最初の一致(_と-)の間のテキストを抽出しようとしています。たとえば、下から5番を取得する必要があります。

MQSeriesRuntime_5-U200491-7.5.0-4.x86_64

Awkフィールドセパレーター(awk -F)を試しましたが、_の後にテキスト全体が表示されます。

6
MO12

あなたはあなたのフィールドセパレータについて創造的である必要があるだけです:

$ awk 'BEGIN {FS="_|-"} {print $2}' input
5

FSの秘訣は、文字列ではないということです。正規表現です。

あなたが以下に要求するようにもう少し完全に説明するために:

awkスクリプトは、着信データが処理される前に実行されるBEGINという名前のコードブロックを定義できます。

このコードブロックを使用して、正規表現をハイフン(-)またはアンダースコア(_)として使用して、フィールド区切り文字(FS)を定義します。

次のコードブロック{print $2}は、2番目のフィールド(つまり、これまでのセパレーター/-|_/で区切られた2番目の文字列)を出力します。これは、検索する5です。プレフィックスのないコードブロックは、awkによって読み取られるすべてのレコードに対して実行されます。

8
DopeGhoti

-Fパラメータを使用することにより、わずかに短いソリューションを実現できます。

$ awk -F'-|_' '{print $2}' input
5
4
steve

sed代替アプローチ:

sed 's/^[^_-]*_\([^_-]*\)-.*/\1/' file
5
1
RomanPerekhrest

Python

_<<<_を使用して目的の文字列をpythonインタープリターのstdinにリダイレクトし、re.split()を使用して、次の2番目の項目を取り出すことができます。 2つのセパレーターで分割される結果のアイテムのリスト。

_$ python -c 'import re,sys; print(re.split("-|_",sys.stdin.readline())[1])'  <<< "MQSeriesRuntime_5-U200491-7.5.0-4.x86_64"                          
5 
_

または、コマンドライン引数として文字列を指定して、_sys.argv[1]_を操作することもできます。

_$ python3 -c 'import re,sys; print(re.split("-|_",sys.argv[1])[1])' "MQSeriesRuntime_5-U200491-7.5.0-4.x86_64"                                       
5
_

これはPython 2および3で機能します。この方法でファイルを処理し、各行から入力を抽出する場合は、次のようにすることができます。

_$ cat input.txt
MQSeriesRuntime_5-U200491-7.5.0-4.x86_64
MQSeriesRuntime_2-U200491-7.5.0-4.x86_64
MQSeriesRuntime_6-U200491-7.5.0-4.x86_64
$ python3 -c 'import re,sys; print("\n".join(map(lambda x: re.split("-|_",x)[1], sys.stdin.readlines())))'  < input.txt                              
5
2
6
_
0

インスピレーション https://stackoverflow.com/a/2957781/53897

echo MQSeriesRuntime_5-U200491-7.5.0-4.x86_64 | Perl -n -e '/_([^-]+)/ && print $1'

cutを最初の区切り文字_で使用して2番目の列を取得し、次にcut-区切り文字で再度使用して最初の列を取得できます。

echo MQSeriesRuntime_5-U200491-7.5.0-4.x86_64 | cut -d"_" -f2 | cut -d"-" -f1 
0
igiannak