• ベストアンサー
  • 困ってます

sedで「(~)」を使って文字列の一部を取り出し

sedで「(~)」を使って、文字列の一部を取り出したいのですが期待した結果になりません。 以下のようなファイルがあります。 そこから、最初に見つかった「A-Z0-9」を含む文字列を取り出したいのですが、 どうしても、2番目にでてくる「0-9」でなる文字列が取り出されます。 環境は、Solaris/Linuxになります。 ■ファイル cat aaa "aaa","bbb","ccc","123456","ddd","eee","fff,"0000","ggg" "aaa","bbb","ccc","AAA123","ddd","eee","fff,"0000","ggg" ■sed sed 's/.*,"\([A-Z0-9].*[0-9]\)",.*$/\1/g' aaa ■結果 0000 0000 期待する結果は、 123456 AAA123 なのですが、 期待した結果を取り出すにはどうしたらよいのでしょうか。

共感・応援の気持ちを伝えよう!

  • 回答数5
  • 閲覧数175
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
  • 回答No.4

No.3 さんに賛成なんだけど、最新の Solaris ではどうか知らないけど ; (マルチステートメント) 使えないので、 sed -e 's/"\([A-Z0-9][A-Z0-9]*\)".*$/\1/' -e 's/^.*,//' aaa みたいにするか、ファイルにスクリプトとして1行づつ書いて -f scriptfile 指定するとかしないといけない気がします。GNU sed 使える環境なら然にあらず。 あと良く使ったのが文中に出てこない文字でマーク付けておいてから、後でいらない部分を消去する方法。 sed -n -e 's/"\([A-Z0-9]*[0-9]\)"/:\1:/1' -e 's/^[^:]*://' -e 's/:.*$//p' aaa /1 の部分を /2 とかすると2番目にマッチした部分を対象に。 : は良く改行コード \n 使ったりするんだけど、sed によってはエスケープ使えずコード自体書かないといけなかったりする。多分 Solaris の sed も

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 いろいろと方法を記載してありがとうございます。 1回ですましてしまおうとして、2回実行することには気がつきませんでした。 参考になります。

関連するQ&A

  • sedで文字列の抜き出し

    ある一部分の文字列を抜き出したく、sedを使用したいと思って試行錯誤しております。 ↓あるファイル内の文字列 aaa bbb=ccc:ddd=eee:fff=ggg: aaa bbb=hhh:ddd=iii:fff=jjj: ※aaaとbbbの間はスペースです。 ※bbb,ddd,fffはある一定のキーワードです。 ※ccc,eee,ggg,hhh,iii,jjjはバラバラの文字列で長さも一定ではありません。 【質問】 上記の文字列の中でddd=の後の文字列(eee,iii)のみを抜き出したいです。 以下のようなsedを試してみましたが、 eee:fff=ggg iii:fff=jjj が抜き出されてしまいます。 sed 's/.*:ddd=\(.*\):\(.*\)$/\1/' 恐れ入りますが、皆様の知恵をお貸し下さい。

  • awk,sedの問題を教えて下さい。

    1)以下のファイルを元にして   aaa bbb ccc   ddd eee ffff   ggg hhh iiii   最初の欄だけとりだしてファイルにする方法は? 2)上記で元のファイルをベースにして1行コマンドで   下記の内容のファイルを作れ。    cat aaa > aaa.txt   cat ddd > ddd.txt   cat ggg > ggg.txt 3)以下のファイルに対してsedコマンドで   file1   file2   file3   下のようなファイルを作成せよ   cat file1 > /dev/null   cat file2 > /dev/null   cat file3 > /dev/null 上記3問宜しくお願い致します。

  • Perlの正規表現について

    Perlの正規表現について質問です. ■質問 aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd eee" aaa bbb ccc ddd eee "fff ggg hhh iii" というような,文字列が書かれているファイルがあるとします. ※ダブルクォーテーションが無い行もあります. ※ダブルクォーテーション内のスペースの数は,行によってそれぞれ異なります. これを,ダブルクォーテーションの中にあるスペースだけ アンダーバーに置換する場合の正規表現を教えて下さい. つまり,下記の出力にしたいです. aaa bbb aaa bbb ccc "ddd" aaa bbb ccc "ddd_eee" aaa bbb ccc ddd eee "fff_ggg_hhh_iii" ■条件 ※ちょっと古いPerlでも動くよう,ゼロ幅肯定/否定後読((?<),(!<))は使わないでください. ※単に実現するだけなら, # cat inputfile | print -pe 'sub f(){}(shift;s/ /_/;return $_;); s/(\".*\")/&f($1)/e;' みたいな感じで置換できそうですが,「正規表現だけで簡単に書けるかどうか」が知りたいのです(正規表現だけで実現出来る場合,そのアルゴリズムを知りたいです).そのため,関数と/eオプションは使わないでください.

    • ベストアンサー
    • Perl

その他の回答 (4)

  • 回答No.5
  • asciiz
  • ベストアンサー率71% (5244/7308)

>しかし、呪文のようですね。 行頭を表す「^」と[ ]内部の否定を表す^、カンマ区切りとカンマ以外を示すための「,」が入り組んでいるのでパッと見訳わかりませんね(笑 私は、添付図のように考えました。 マッチした4番目の文字列で、行全体を置き換えるので、第4項目を取り出せます。 この正規表現では「データにカンマが含まれないものに限る」という条件が付くのも理解できるかと…。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 詳細な説明を解説図付きでありがとうございます。 勉強になります。

  • 回答No.3
  • M_Sato
  • ベストアンサー率55% (497/888)

以下のように、最初に後ろを切って、次にカンマから前を切ったらどうでしょう。これなら求めるデータがどの位置にあっても適応できると思います。 s/"\([A-Z0-9][A-Z0-9]*\)".*$/\1/;s/^.*,//

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 たしかに、取り出したい文字列以降を捨ててしまえばできます

質問者からの補足

>たしかに、取り出したい文字列以降を捨ててしまえばできます マルチステートメント? で、最初に後ろを切ってしまうということだったですね。 内容をよく確認せずまちがった返事でした。 マルチステートメント使えませんです。

  • 回答No.2
  • Wap58
  • ベストアンサー率33% (29/86)

sed -r 's/.+?,"([A-Z0-9]+)",.+$/\1/' aaa 手元に実行環境ないけど これでいけんじゃないの?

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 確認させてただきます。

質問者からの補足

Linuxでためしてみましたが、できませんでした。 2番目が出力されます。

  • 回答No.1
  • asciiz
  • ベストアンサー率71% (5244/7308)

「.*」は、任意の文字、0文字でも何文字にでもマッチしてしまうので、安易に使ってはいけません。 特にマッチ文字列中でいくつも使うと、最初のものから最長になるようにマッチします。 今回の例では、最初の「.*,」の部分が「"aaa","bbb","ccc","123456","ddd","eee","fff",」にまでマッチするから、"0000"が取り出されてしまうというわけです。 さてそこで、任意文字にマッチしてしまう「.」ではなく、「カンマ以外」を示す「[^,]」を使ってみましょう。 sed 's/^[^,]*,[^,]*,[^,]*,"\([^,]*\)",.*/\1/g' aaa これで、カンマ区切りの「第4項目」を取り出せるんじゃないでしょうか。 まあ、文字列にカンマが含まれる場合はこれでも困りますけどね…。 sedはダブルクォーテーションの対応なんか気にしないので、項目区切りのカンマだろうが文字列中のカンマだろうが同一視してしまいます…。

共感・感謝の気持ちを伝えよう!

質問者からのお礼

ありがとうございます。 期待した結果となりました。 しかし、呪文のようですね。

関連するQ&A

  • エクセルマクロ 特定の文字列を含む行を削除

    エクセルマクロ 特定の文字列を含む行を削除 エクセルのマクロについて教えてください。 下の中から列を限定せず、すべての行でAAA、CCCのいずれかがある場合、 その行ごと、すべて削除したいのです。 時に削除したい特定の文字列が数十種類になるため、 マクロ起動時に削除したい特定の文字を記述したファイルを読み込み、それから 削除できるようにしたいのです。場合によってはそのファイルを編集し、 削除したい文字列を変更したいのです。 ご教示いただだけないでしょうか A列 B列 C列 1 AAA BBB CCC 2 BBB CCC FFF 3 DDD BBB FFF 4 AAA CCC DDD 5 GGG RRR UUU 行中にAAA、BBBがある場合、削除したい ↓ A列 B列 C列 5 GGG RRR UUU マクロを実行し、上記の結果にしたい。

  • 配列の移動

    TEXTファイルに文字列を書き込んだり削除したり移動したりするプログラムを作成していますが、 aaa bbb ccc ddd eee fff ggg hhh iii このような内容を 1,aaa bbb ccc 2,ddd eee fff 3,ggg hhh iii のように上から順番に配列化して番号を指定して移動させたいのですが、 3の配列を2の上(配列1と配列2の間)や下(配列2と配列3の間)に移動するのにはどのようにしたら良いのでしょうか?

    • ベストアンサー
    • Perl
  • 抽出して並べ替えたい

    初めまして 非常に悩んでいます。 エクセルシートの列に下記のようにデータが並んでいます。(文字列) AAA bbb ccc (空白) BBB ddd eee (空白) AAA bbb ccc (空白) AAA eee ggg 並べ替え後 AAA AAA BBB bbb eee ddd ccc ggg eee 尚、列上でセル位置は任意で、空白行も任意です。(1つ以上です) できれば関数でお願いします。 VBAの場合、使用したことがないので詳しくお願いします。

  • C言語による「テキストファイルの読み書き(fprintf)」について

    C言語による「テキストファイルの読み書き(fprintf)」について質問です ずぶの初心者ですが、既知のファイルの1行目に指定した文字列を付加させるプログラムを作りたいと思っています。 以下のように作りました。 ------------------------------------------------------------ #include <stdio.h> int main(void) { FILE *fp; fp = fopen("test.csv","r+"); fprintf(fp,"コントロールカラム1,コントロールカラム2,・・・(略)・・・,コントロールカラム56\n"); fclose(fp); return 0; } ------------------------------------------------------------ このとき「test.csv」の内容が以下のようであったとします。(容量は1MBくらいです。) 001,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj この状態でプログラムをコンパイルして実行すると、「test.csv」の内容が以下のようになってしまいます。(一行目が消える) AAA,BBB,CCC,DDD,EEE 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj またcsvの行が増える度に妙な挙動になっていきます・・・(一行あいたり、先頭行が5行ほど消えたり) 希望する動作としては コントロールカラム1,コントロールカラム2,・・・(略)・・・,コントロールカラム56 001,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj 002,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj ~(略) 5000,aaa,bbb,ccc,ddd,eee,fff,ggg,hhh,iii,jjj のようになるようにしたいのですがどのようにすればよいのでしょうか。 よろしくお願いします。 (使用ソフト:Borland C++ Compiler, Cpad) 参考にしたサイトの項目:http://homepage3.nifty.com/mmgames/c_guide/17-01.html

  • Excelの関数に詳しい方、お願いします。

    わかりづらい説明かもしれませんが、よろしくお願いします。 例として、 AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF AAA*BBB*CCC*DDD*EEE*FFF ・ ・ ・ といった文字列がエクセルの先頭列A1&#65374;A100までずらりと並んでいるとします。 各アルファベットには任意の数字(日付など)が入るとして、この並んだ百件のデータからCCCの部分の最大値を表示するための適切な関数があれば教えていただけないでしょうか? 現在少々急いでいるため言葉足らずで申し訳ありませんが、よろしくお願いいたします.

  • EXELで困っています。どなたか助けてください!

    お世話になります。早速ですが・・・ 下記のような表があります。 ┌──────┬─-─┬─-─┬─-─┬─-─┬─-─┬─-─┬─-─┐ │分類項目・・・・│AAA │BBB │CCC │DDD │EEE │FFF │GGG │     ├──────┼─-─┴─-─┴─-─┴─-─┴─-─┴─-─┴─-─┤ │「、」区切り・・・│AAA、BBB、CCC、DDD、EEE、FFF、GGG        │ ├──────┼──────────────────────-─┤ │「 」区切り・・・│AAA BBB CCC DDD EEE FFF GGG        │     ├──────┼──────────────────────-─┤ │「,」区切り・・・・│AAA,BBB,CCC,DDD,EEE,FFF,GGG             │ └──────┴──────────────────────-─┘ ■不特定の分類項目(何が記入されるかわかりません)のAAなどの  項目を上図、および、下記のように自動的に変換というか、並べ  られるようにしたいと思っています。 (1)「、」区切り(全角句点区切り) (2)「 」区切り(全角スペース区切り) (3)「,」半角句点区切り ■【質問1】VBAマクロを使わず関数などの処理にてできない       ものでしょうか?   また、  【質問2】(1)上図で「、」で区切ったもの        (2)同様に「 」で区切ったもの        (3)同様に「,」 で区切ったもの        例えとして⇒○「AAA、BBB       」             ⇒×「AAA、BBB、、、、、、、」        このようにしたいのですが?   【質問3】いずれの場合も、その新しくできた文字列を他の        ソフトウェアにコピペしようとすると、関数の数式が        コピペされてしまします。        もちろんセルをワンクリックで選択すると、値だけが        コピペできます。        この点を初心者でも失敗(数式のコピペではなく)する        ことなく、値だけをコピペすることが可能でしょうか? どうかよろしくお願いいたします。 <( _ _ )> 

  • VBAでCSV内にある改行を取る方法

    あるシステムが吐くcsvファイルの項目の中に改行が入っているものがあります。 例) 01,aaa,bbb(改行)bbb,ccc(改行) 02,ddd,eee,fff(改行) 03,ggg(改行)ggg,hhh,iii(改行) このCSVファイルをエクセルのマクロで読み込んでシートに展開したい のですが、項目中にある改行で別レコードを認識してしまいます。 結果) A B C D ---+---+---+--- 01 aaa bbb  bbb ccc 02 ddd eee fff 03 ggg ggg hhh iii これを以下のようにしたいのですが・・・ A B C D ---+------+------+---- 01 aaa bbbbbb ccc 02 ddd eee fff 03 gggggg hhh iii どうやればよいでしょうか? ご教授お願いいたします。

  • 2回以上繰り返される文字列の削除について

    以下の文字列(置換前)で、-aaa について複数存在しているので、 最初の -aaa を残して残りの -aaa をすべて削除したいと考えています。 1回の正規表現+置換で行いたいのですが、どのようにいすればよいでしょうか? 【置換前】 -bbb -aaa -ccc -aaa -ddd -eee -aaa -fff 【置換後】 -bbb -aaa -ccc -ddd -eee -fff ちなみに、複数回の正規表現+置換を使ってよい場合は、 while (m/( -aaa.*) -aaa/) { s/( -aaa.*) -aaa/$1/; } でできると考えています。(動作確認まではしていないので間違ってるかも)

    • ベストアンサー
    • Perl
  • sedで特定行を抽出したいです

    はじめまして、 下記のようなファイルがあり、sedで特定文字列(@@@, @@@@, @@@@@)を含む行のみを一回で抽出したいです。 sed -n -e "/p=300/,/eee/p" input > output' だと 不要な行も入ってしまいます orz... sedはWindows上のsed Logos 2.42を使用しています。 どのように書けば対象行のみを抽出できるか、ご教授をお願いいたします。 [ 読込み対象ファイル ] ***, @@@, @@@@, @@@@@は雑多な文字列 最初に不要な行が10~15行 <div class="aaa"> <a href="http://www.***.***/?p=300&***">@@@</a> </div> <div class="bbb"> <ul class="ccc"> <li class="ddd">@@@@</li> <li class="eee">@@@@@</li> <div class="aaa"> <a href="http://www.***.***/?p=300&***">@@@</a> </div> <div class="bbb"> <ul class="ccc"> <li class="ddd">@@@@</li> <li class="eee">@@@@@</li> 以下<div class="aaa">から<li class="eee">@@@@@</li>まで20回繰り返し。

  • awkやsed等で特定の文字間を抜き出す

    cat text aaaa bbbb <AAA> ccc ddd <BBB> eee とあるときに <AAA> ccc ddd <BBB> だけ抜き出したいです。 どのようにすればよいでしょうか?