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

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

新規登録して質問してみよう
ただいま回答率
85.48%
シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

Q&A

解決済

4回答

1071閲覧

列要素を行に並べなおす処理を行いたい

yone_yone

総合スコア28

シェルスクリプト

シェルスクリプトは、UNIX系のOSもしくはコマンドラインインタプリタ向けに記述されたスクリプト。bash/zshといったシェルによって実行されるため、このように呼ばれています。バッチ処理などに使用されており、テキストファイルに書かれた命令を順に実行します。

ファイル

ファイルとは、文字列に基づいた名前又はパスからアクセスすることができる、任意の情報のブロック又は情報を格納するためのリソースです。

Linux

Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

0グッド

0クリップ

投稿2019/12/27 16:16

編集2019/12/27 17:05

ファイルの処理についての質問をさせていただきます。

text1.txtの内容をtext2.txtにできるスクリプトを作りたいと考えています。

text1

1text : [[111] 2[22] 3[33]] 4text : [[444] 5[55] 6[66]] 7text : [[777] 8[88] 9[99]] 10text : [[12] 11[34] 12[56] 13[78]] 14text : [[90] 15[23] 16[45] 17[67]] 18text : [[24] 19[56] 20[76] 21[85]]

text2

1111 444 777 222 55 88 333 66 99 4 512 90 24 634 23 56 756 45 76 878 67 85 9...

作成したスクリプトが以下になります。

script

1cat text1.txt | sed 's/text//g' | sed -e 's/[//g' -e 's/]//g'

実行結果が以下になります。

: 111 22 33 : 444 55 66 : 777 88 99 : 12 34 56 78 : 90 23 45 67 : 24 56 76 85

この後がどのように処理したらよいか分からず、手作業になってしまいます。

分かる方がいましたら、回答いただけると助かります。
※ご回答いただいた内容に質問させていただくこともあるかと思いますので、
※よろしければご返信いただければと思います。

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

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

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

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

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

otn

2019/12/28 00:56 編集

text: から始まる行を3行ずつ組み合わせるということですか? 3行というのはデータ内容によらないで固定? あと、お書きのスクリプトだとエラーですが??コピペ間違い?
yone_yone

2019/12/27 17:04

>text: から始まる行を3行ずつ組み合わせるということですか? その通りです。 >3行というのはデータ内容によらないで固定? そこは固定でお願いします。 >あと、お書きのスクリプトだとエラーですが??コピペ間違い? こちらの手違いでコピペ間違いです。 質問内容の修正を行いました。
退会済みユーザー

退会済みユーザー

2020/01/22 02:25

空のデータ[]が存在する可能性はありますか? また、ある場合はどのように出力すると良いですか?
guest

回答4

0

ベストアンサー

行列の転置には、pasteコマンドを使うのですが、あんまりきれいにいかないですね。

Bash

1#!/bin/bash 2cat <<EOF | 3text : [[111] 4[22] 5[33]] 6text : [[444] 7[55] 8[66]] 9text : [[777] 10[88] 11[99]] 12text : [[12] 13[34] 14[56] 15[78]] 16text : [[90] 17[23] 18[45] 19[67]] 20text : [[24] 21[56] 22[76] 23[85]] 24EOF 25sed -n '/^text/{s/^.*[//;s/]//;h} 26/^[.*[^]]]$/{s/[][]//g;H} 27/]]$/{s/[][]//g;H;g;s/\n/,/gp}' | 28while read x && read y && read z 29do 30 paste <(echo "$x"|tr , '\n') <(echo "$y"|tr , '\n') <(echo "$z"|tr , '\n') 31 echo #区切りの空白行 32done

sedで、textから]]までをカンマ区切りで1行にまとめて、それを3行読んでpasteします。

最後のpasteの前処理でカンマを改行に置換するのは、別案で、

Bash

1paste <(echo "${x//,/ 2}") <(echo "${y//,/ 3}") <(echo "${z//,/ 4}")

でもいいです。どっちがいいか微妙なので、両方書いておきます。

データにカンマが含まれる可能性があるなら、タブなど含まれない文字に変更してください。

投稿2019/12/28 00:27

otn

総合スコア84557

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

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

yone_yone

2019/12/28 04:49

回答ありがとうございます。 ベストアンサーとさせていただきます。
退会済みユーザー

退会済みユーザー

2020/01/24 05:17

鈍重すぎてビンテージコンピュータみたいに動作する。 入力を1,000行に増やすと以下の結果 real 0m13.999s user 0m4.969s sys 0m14.323s まじで、わざとやってない? 懐かしいけどさ
退会済みユーザー

退会済みユーザー

2020/01/24 05:41

質問者の仕様を満たしたかどうかは不明だが、 GAWKのみを使った結果は以下(同1,000行の入力) real 0m0.093s user 0m0.015s sys 0m0.061s
otn

2020/01/24 05:57

3データ毎にプロセスを7つ起動しますからね。 修正版にすると4つになるので少しましになるでしょう。 小規模データ(3x3)の、繰り返したくさん、のパターンだと、コマンド起動は遅いです。 大規模データで、繰り返し無しだと、pasteが生きると思いますが。
退会済みユーザー

退会済みユーザー

2020/01/24 06:41

まるでMSXみたいな動作で暖かな気持ちになれた けれど、古い教科書にも載っているスタンダードなスクリプトと 数百倍の実行速度差は、ちょっとどうかと思ったまで あなたの回答はいつも興味深くそして面白い
guest

0

GAWK のみで行うなら

awk

1BEGIN { 2 RS = "]]"; 3} 4 5# sed&awkプログラミング13章"transpose-行列の転置"参照のこと 6{ 7 for (i = 3; i <= NF; i++) { 8 if (pos = match($i, /[^[]]+/)) { 9 if (ssv[i] == "") ssv[i] = substr($i, pos, RLENGTH); 10 else ssv[i] = ssv[i] " " substr($i, pos, RLENGTH); 11 } 12 } 13 if (NR % 3 == 0) { 14 PROCINFO["sorted_in"] = "@ind_num_asc"; 15 for (i in ssv) print ssv[i]; 16 print ""; 17 delete ssv; 18 } 19} 20 21# 最後のデータセットが3の倍数でない場合 残りを吐き出す 22END { 23 PROCINFO["sorted_in"] = "@ind_num_asc"; 24 for (i in ssv) print ssv[i]; 25}

配列添字iについて
初期値3からインクリメントされていくので、
PROCINFOによるソートは必要ないかもしれません。

result

111 444 777
22 55 88
33 66 99

12 90 24
34 23 56
56 45 76
78 67 85

投稿2020/01/21 15:28

編集2020/01/22 01:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

次のようなアプローチで処理してみました。

  1. text ごとに1行にまとめる
  2. [, ] を取り除く
  3. 3行ごとに空行を挟む

sh

1$ awk -f sample.awk text1.txt | tr -d '[]' | awk 'NR % 3 == 1 && NR != 1 {print ""} {print}'

text ごとに1行にまとめる sample.awk の内容は次のようになります。

awk

1/^text/ { 2 # 配列 xs の内容を空白区切りで出力する 3 for (i in xs) { 4 if (i != length(xs) - 1) ORS=" " 5 else ORS="\n" 6 print xs[i] 7 } 8 9 # 配列 xs をクリア 10 split("", xs) 11 12 # text で始まる行は末尾フィールドのみ配列 xs に追加する 13 i=0;xs[i]=$NF 14 next 15} 16 17# text で始まらない行は配列 xs にその内容を追加する 18{xs[++i]=$0} 19 20END { 21 # 最後の text を出力する 22 for (i in xs) { 23 if (i != length(xs) - 1) ORS=" " 24 else ORS="\n" 25 print xs[i] 26 } 27}

投稿2019/12/28 00:43

編集2019/12/28 00:46
kit494way

総合スコア317

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

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

kit494way

2019/12/28 00:57

text2.txt のように転置できてませんでした。無視してください。すみません。
otn

2019/12/28 01:00

質問を読み違えてます。
kit494way

2019/12/28 01:04

はい。すみませんでした。
guest

0

sh

1cat text1.txt | sed -e "N;N;s/\n//g" | sed -e "s/^text : [[//" | sed -e "s/][/ /g" | sed -e "s/]]$//" > text2.txt

投稿2019/12/28 00:41

ikapy

総合スコア1167

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

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

otn

2019/12/28 00:53

質問を読み違えてます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問