• ベストアンサー

列を指定してコマンドでの置換

テキストファイルの1列目2列目に対して、XXXXX.Yの後の.以降の文字or数字を全てコマンドで削除して、XXXXXとしたいです。 どのような方法がありますでしょうか? sedでは列指定はできないと思うので。

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

  • ベストアンサー
  • asciiz
  • ベストアンサー率70% (6871/9771)
回答No.1

>sedでは列指定はできないと思うので。 列っていうのはどういう物でしょう? →特定の「セパレータ」で区切られた間にあるもののことです。 なのでCSVであれば、行頭「^」から、最初のセパレータ「,」までの間が、1列目です。 その間の任意文字列を指定したいわけですが、「.*」とやると、カンマまで含んでしまいます。 そこで、カンマ以外の文字、「[^,]」が任意個「*」続いた文字列、を項目と考えます。 まとめると、 ^[^.]*, というパターンで、1列目(カンマ込み)を取り出すことができます。 今度は、置換したい部分。 「[^,]*」は、XXXXX.YYY にマッチします。 「[^,]*\.[^,]*」も、XXXXX.YYY にマッチしますが、前半はXXXXXの部分、後半はYYYの部分にマッチします。 ※複数ドットがあった場合は、一般的に前の方が長くなるようにマッチします まあ複数ドットがある場合はあとで考えるとして、削りたいのは後半部分。 マッチする前半を部分文字列に登録し、 ([^,]*)\.[^,]* 置換パターンで $1 とすれば、前半のみ残せることになります。 s/([^,]*)\.[^,]*/$1/ これと最初の列指定を組み合わせれば、 s/^([^,]*)\.[^,]*,/$1,/ これで、1列目の XXXXX.YYY を XXXXX に置換できるでしょう。(1) 2列目のパターンは別にします。 s/^([^,]*),([^,]*)\.[^,]*,/$1,$2,/ 1列目はそのまま持ってきて、2列目で先ほどの置換をします。(2) 2列両方を置換するには、(1)(2)の両方を記述する、となるでしょう。(回答) -- なお、 s/([^,]*)\.[^,]*,([^,]*)\.[^,]*,/$1,$2,/ というのが考えられますが、これは良く考えてみると、1列目と2列目が両方 XXXXX.YYY 形式だった場合にのみ、置換されます。 どちらかの列にドットが含まれなければ、パターンがマッチせず、置換も起こりません。 ---- …とここで一応の回答が得られましたが、上記のパターンで困るのは、「項目中にカンマが含まれる場合」です。 CSVでは、項目をダブルクォートでくくった場合は、その中のカンマはセパレータと見なさないルールですが、上記パターンはそれを無視して置換してしまいます。 場合によってはCSVデータを破壊してしまうでしょう。 カンマ区切りのCSVではなく、タブ文字(\t)区切りのTSVデータの方が、こういう処理をするのが楽です。(さすがにタブ文字は一般文字列に含まれないという前提で。) 上記パターンの「,」を「\t」に置き換えれば、TSVデータに対して適用できます。 -- あと複数のドットがある場合に前半を短くマッチさせたいならば、項目パターンとして ([^,.]*)\.[^,]* というものが考えられます。

すると、全ての回答が全文表示されます。

関連するQ&A