web-dev-qa-db-ja.com

bashを使用して、角括弧の間から数値を抽出します

私のファイルは次のようになります。

[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);  
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);

すべての新しい行は、パターン[number]で始まります。すべての行は、パターン);で終わります。

すべての行の先頭から角かっこ内の数字を抽出し、新しいファイルに書き込む必要があります。ファイルの行数が事前にわかりません。

3
user3069326

これは、単一の grep コマンドで実現できます。これは、GNU grepで Perl正規表現-P)を使用できるためです。これは ゼロ幅のルックアラウンドアサーション\Kおよび(?=)、この場合):

grep -oP '^\[\K\d+(?=\])' infile

書かれているように、それはあなたの端末に出力を送信します。ファイルにリダイレクトするには、次を使用します。

grep -oP '^\[\K\d+(?=\])' infile > outfile

この方法には、簡潔さと単純さという利点があります。次のテキストと一致します

  • \K)が前に付きます

    • [ character(\[)-\は、[として必要です。そうでない場合、正規表現で特別な意味を持ちます。
    • 行の先頭に表示される(^);
  • 1つ以上の(+)数字(\d)で構成されます。

  • 後に((?=))が続きます

    • ]文字(\])-[と同様、\]を強制的に文字通りに一致させます。
12
Eliah Kagan

sedの使用:

  • < inputfile sed -n 's/^\[\([0-9]*\)\].*$/\1/p' > out

コマンドの内訳

  • < inputfileinputfileの内容をstdinにリダイレクトします
  • -n:出力を抑制します
  • > outstdoutの内容をoutにリダイレクトします

正規表現の内訳

  • s:置換を実行します
  • /:正規表現を開始します
  • ^:行の先頭に一致
  • \[[文字に一致
  • \(:キャプチャグループを開始します
  • [0-9]*:任意の桁数に一致
  • \):キャプチャグループを停止します
  • \]]文字に一致
  • .*:任意の数の任意の文字と一致します
  • $:行末に一致
  • /:正規表現を停止する/置換を開始する
  • \1:最初のキャプチャグループに置き換えます
  • /:置換を停止します
  • p:一致する行のみを出力します

grep + trの使用(UbuntuとgrepがPCREをサポートしていない別のOSの両方で実行するメソッドが必要な場合は、 Eliah Kaganのgrep- onlyバージョン を参照してください):

  • < inputfile grep -o '^\[[0-9]*\]' | tr -d '[]' > out

コマンドの内訳

  • grep< inputfileinputfileの内容をstdinにリダイレクトします
  • -o in grep:一致のみを出力します
  • tr-d:文字を削除します
  • tr> outstdoutの内容をoutにリダイレクトします

正規表現の内訳

  • ^:行の先頭に一致
  • \[[文字に一致
  • [0-9]*:任意の桁数に一致
  • \]]文字に一致
7
kos

Perlの方法:

Perl -ne 'print "$1\n" if /^\[([0-9]*)\].*/' testdata > out

またはawkを使用:

awk 'match($0, /^\[[0-9]*\]/) {print substr($0, RSTART + 1, RLENGTH - 2)}' testdata > out

両方の場合に正規表現を使用しました:

^\[[0-9]*\]

説明

  • /^\[[0-9]*\]/

    • ^文字列の開始位置をアサートします

    • \[は文字[と文字通り一致します

    • [0-9]*は、以下のリストにある単一の文字と一致します

      • 量指定子:*ゼロ回から無制限の時間、可能な限り多くの回数、必要に応じて返す[貪欲]

      • 0-9 0〜9の範囲の単一文字

    • \]は文字]と文字通り一致します

    Regular expression visualization
    (ソース: debuggex.com

    Debuggexデモ

3
A.B.

Bashでこれを使用します。

 grep -oh '\[[0-9].*\]' mytestfile | sed 's/.*\[\([^]]*\)\].*/\1/g' > myresultfile
2
Frantique

pythonモジュールを使用し、2つの状況を考慮したreソリューション:

#!/usr/bin/env python2
import re
with open('/path/to/file.txt') as f:
    for line in f:
        digits_case_1 = re.search(r'(?<=^\[)\d+(?=\])', line)
        digits_case_2 = re.search(r'(?<=^\[)\d+(?=\].*\);$)', line)
        if digits_case_1:
            print 'Not considering ");" at end: ' + digits_case_1.group()
        if digits_case_2:
            print 'Considering ");" at end: ' + digits_case_2.group()

出力:

Not considering ");" at end: 581
Not considering ");" at end: 50
Considering ");" at end: 50

ここでは、あなたの質問が私には明らかでないように、2つの状況を考慮しました。

  • digits_case_1は、行の先頭に[]の間の数字の一致を出力します。行が);で終わるかどうかは考慮しません。

  • digits_case_2は、行が[]で終わる場合にのみ、行の先頭で);の間の数字を出力します。

1
heemayl

cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['

進行状況:§

$ FILE=/tmp/tmp.tmp

$ cat $FILE
[581]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50]((((((((501:0.00024264,451:0.00024264):0.000316197,310:0.000558837):0.00857295,((589:0.000409158,538:0.000409158):0.000658084,207:0.00106724):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);

$ cat $FILE | awk -F\] '{ print $1 }'
[581
):0.00806454):0.0429702,(((198:0.00390205,91:0.00390205):0.016191,79:0.0200931):0.0147515,(187:0.00133008,50:0.00133008):0.0335145):0.0172574):0.
127506,((140:0.00253019,117:0.00253019):0.0533693,(((533:0.00728707,(463:8.80494e-05,450:8.80494e-05):0.00719902):0.0217722,389:0.0290593):0.0253
931,(((141:0.018004,107:0.018004):0.0143861,(111:0.00396127,(106:0.00161229,12:0.00161229):0.00234898):0.0284289):0.0145736,(129:0.0195982,((123:
0.0105973,66:0.0105973):0.0084867,10:0.019084):0.000514243):0.0273656):0.00748854):0.00144709):0.123708):0.000944439,((181:0.00108761,71:0.00108761):0.0819772);
[50

$ cat $FILE | awk -F\] '{ print $1 }' | grep '\['
[581
[50

$ cat $FILE | awk -F\] '{ print $1 }' | grep '\[' | tr -d '['
581
50

$

§ manコマンドにアクセスできない場合。

0
boardrider