質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

4回答

1313閲覧

rubyワンライナー で文字列処理を複数行うには

taro373

総合スコア189

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

0グッド

0クリップ

投稿2021/10/22 06:25

編集2021/10/22 06:26

rubyのワンライナーを使ってみようとして勉強しています。
カンマ区切りを分割まではできたのですが、もう一つ処理を加えようとして、すんなりとできませんでした。
タブ区切りのファイル入力して、3列目にある文字列をカンマ区切りを取り除きました。カンマ区切りを分割した後、文字列を加工するにはこの方法しかないのでしょうか。
stripで前後の空白を取り除けないのでしょうか。

まずはstripをワンライナーで実行

~ $ ruby -e 'puts(" aa ".strip)' aa<== こうしたい

実際の入力ファイル

~ $ cat test.tsv col1 col2 col3 col4 1 a A, B,X x 2 b S ,T,U y 3 c V,W ,C z

3列目を入力して、カンマ区切りを改行に変更  当然“B”の前の空白は出力される

~ $ cat test.tsv |ruby -F'\t' -ane 'puts($F[2].gsub(/,/,"\n")) if $. != 1' A B X S T U V W C

このときにカンマ区切りの前後に空白があれば除去したいのですが、
stripでは取り除けませんでした

~ $ cat test.tsv |ruby -F'\t' -ane 'puts($F[2].gsub(/,/,"\n").strip) if $. != 1'

gsubであれば除去できました

~ $ cat test.tsv col1 col2 col3 col4 1 a A, B,X x 2 b S ,T,U y 3 c V,W ,C z 4 d F G, H I X ~ $ cat test.tsv |ruby -F'\t' -ane 'puts($F[2].gsub(/,/,"\n").gsub(/^ */,"").gsub(/ *$/,"")) if $. != 1' A B X S T U V W C F G H I

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

console

1cat test.tsv |ruby -ane 'puts $_.split("\t")[2].split(",").map(&:strip)'

実行例

イメージ説明

投稿2021/10/24 07:33

katoy

総合スコア22324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taro373

2021/10/26 05:04 編集

mapの使い方は | 配列の入った変数.map {|変数名| 処理内容 } だとしか理解しておらず、調べました。ワンライナーだけでなくRubyもあらためて勉強になりました。ありがとうございました。 各要素にメソッドを適用するときは以下のように省略して記述することができます。 | オブジェクト.map(&:メソッド名) 省略して記述した場合は、すべての要素に対して&の後にシンボルで指定したメソッドが繰り返し実行され、結果が配列として返されます。
guest

0

stripは、文字列の先頭と末尾の(連続した)空白文字だけ削除します。途中の空白はそのままです。

sh

1ruby -F'\t' -ane 'puts($F[2].gsub(/ *, */,"\n")) if $. != 1'

でしょうか。

投稿2021/10/22 13:44

編集2021/10/22 13:47
otn

総合スコア85901

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taro373

2021/10/26 05:06

おっしゃる通りです。stripを使わずに区切り文字を考えるだけで、“やりたいこ”とが実現できることがわかりました
guest

0

愚直にやるとこんな感じでしょうか?
split("\t")[2].split(',').each {|c| puts c.strip}

  1. タブで分割
  2. 3番目の要素をカンマで分割
  3. 分割した各要素を空白を削除し出力

投稿2021/10/22 08:21

satoshih

総合スコア799

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taro373

2021/10/26 05:07

ワンライナーとはいえ、区切ったあとは、eachで処理しないと、たしかにそうですね。ワンライナーの勉強になりました。ありがとうございました。
guest

0

カンマの前後 だけなら gsub(/,/,"\n") -> gsub(/ *, */,"\n")
" " を \s にしてしまうと tabとかがあるので順番に注意となります。
tabの前後 とか 全体の前後の空白も問題ならまた変わりますが

ああ
「当然“B”の前の空白は出力される」か
問題を正確に定義しないと正しい答えは来ません。
カンマ区切りでカラム分割し、カラムないをタブで分割した2つ目を出力する。
ただし タブでぶんかつしたあと前後の空白は削除する

ですか?
split(/ *, */).each{|clm| puts clm.split(/ *\t */)[1]} とか
split(/ *, */).each{|clm| puts clm.split(/\t/)[1]} とかでしょうか

投稿2021/10/22 07:40

編集2021/10/22 07:55
winterboum

総合スコア23567

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

taro373

2021/10/22 08:20

stripでは除去ができないのでしょうか? -F'\t' で切り分けて$F[2]を使うのではなく まず「カンマ区切りでカラム分割」しないと処理できないのでしょうか? すみません、ワンライナーの考え方自体に慣れていません。 ワンライナーでなければ、 ・3カラム目を取り出す ・カンマで区切る ・ループしてstripして出力 ・次の行を処理 のロジックになると思ったのですが.....
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問