OmniAICreator/Qiita-1.07M huggingface dataset:
マテリアルのアニメーションをベイクするスクリプト

Blender内でマテリアルにつけたアニメーションを他のソフトに持っていきたい
といった趣旨の話題を見かけて
![21032701.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/2a039b45-6d43-0b26-90d1-be2e54f630b5.gif)
そういったデータを受け渡しのできるフォーマットもないので
マテリアルをベイクした連番画像を作成できればいいのでは？と思い作成してみました

```py:y_BakeMaterialAnimation.py
import bpy
import os
# ベイクする画像のサイズ
img_width = 1024
img_height = 1024

# ベイク用のノードの作成
def criete_bake_terget(mat, image, uv_layer):
    node_tree = mat.node_tree
    img_node = node_tree.nodes.new("ShaderNodeTexImage")
    img_node.image = image
    uv_node = node_tree.nodes.new("ShaderNodeUVMap")
    uv_node.uv_map = uv_layer.name
    node_tree.links.new( uv_node.outputs[0], img_node.inputs[0] )
    #ベイク対象はアクティブなノード
    node_tree.nodes.active = img_node
    return(img_node, uv_node)
# ベイク用マテリアルの消去
def crean_beke_terget(mat, beke_nodes):
    img_node = beke_nodes[0]
    uv_node = beke_nodes[1]
    mat.node_tree.nodes.remove(img_node)
    mat.node_tree.nodes.remove(uv_node)

scene = bpy.context.scene
#選択されているオブジェクトを取得
active_object = bpy.context.active_object
mat = active_object.active_material
# 保存先の設定
render_fpath = scene.render.filepath
save_dir = os.path.dirname(render_fpath)
# ベイク対象の画像の作成
img_name = "bake_image"
image_object = bpy.data.images.new(name=img_name, width=img_width, height= img_height)

# 選択しているUVの取得
uv_layer = active_object.data.uv_layers[ active_object.data.uv_layers.active_index ]
# アニメーション範囲の取得
frame_start = scene.frame_start
frame_end = scene.frame_end
# ベイク用ノードの作成
nodes = criete_bake_terget(mat, image_object, uv_layer)
# 現在のレンダリング設定の退避
ref_engine = scene.render.engine
scene.render.engine = 'CYCLES'
# 現在のサンプル数の退避
ref_sampkung = scene.cycles.samples
scene.cycles.samples = 8
# アニメーションのベイク
for t in range(frame_start,frame_end +1) :
    # シーケンスカーソルの移動
	bpy.context.scene.frame_set( t )
    # ベイク
    bpy.ops.object.bake(type='DIFFUSE', pass_filter={'COLOR',}, use_clear=False)
    # 画像の保存名
    f_name =  "bake_%s.png" % (str(t).zfill(6))
    img_path  = os.path.join(save_dir,f_name)
    #画像の保存
    image_object.save_render(filepath=img_path)
# サンプリング数を元に
scene.cycles.samples = ref_sampkung
# レンダリングエンジンを元に
scene.render.engine = ref_engine
# ベイク用マテリアルの消去
crean_beke_terget(mat, nodes)
```
アドオンでなく　スクリプトエディッタで実行するスクリプトです。

スクリプトを実行すると　アウトプットプロパティの出力パスに設定してある場所に
bake_000000.png といった具合に画像ファイルを出力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151493/a35231dd-98a7-b9dd-60e6-9839b813b61e.png)
書き出しするフレームはレンダリング範囲にしているフレーム
書き出すマテリアルはアクティブなもののみ、
書き出しに利用するUVはオブジェクトデータで選択されているUVマップになります。

今回はシンプルな機能のみですが要望があればアドオン化したいと思います
Power automate で Mail merge（差込送信） を作ってみた。

#目次
・[はじめに](#はじめに)
・[背景（飛ばしてOK）](#背景（飛ばしてOK）)
・[フロー](#フロー)
・[準備するもの](#準備するもの)
・[解説](#解説)
・[まとめ](#まとめ)
・[参考文献](#参考文献)

#はじめに
　本記事を見つけて頂き、ありがとうございますm(_ _)m
　本記事では、
　<font color="Magenta">**Excel online のテーブルから値を抽出してメールを送るFlow（要はMail merge、差込送信）**</font>
　の作成方法を紹介します。
　拙い点が多々ありますが、少しでもお力になれれば嬉しいです、飛び跳ねます、踊ります。

#背景（飛ばしてOK）
　最近、職場でOffice365を導入しました。それに伴って色々変わって、メーラーがThunder birdからOutlookに変わりました。つまりThunderbirdの便利機能のMail merge（差込送信）も使えなくなりました...。
　一応、Wordを用いてMail mergeに似た差込送信ができるのですが、
　・Word表示とOutlook表示が異なる
　・共有メールアドレスで送信が行えない
などの問題があり、使い勝手が悪く悩んでいました。というわけで色々調べていたらこんな記事が！！↓
[★Microsoft Flowでメール自動配信をする★](https://qiita.com/g-mwam/items/388c94f55b9bd670f5fc)
　
　...もはや[g-mwam様](https://qiita.com/g-mwam)の記事が答えになっているのですが、おつむが足りず理解できず引用することができなかったので、
　<font color="Magenta">**Excel online のテーブルから値を抽出してメールを送る**</font>
だけを行うFlowを作成することにしました。

#フロー
　1つ目の画像がflowの全体図、2つ目がApply to each の中身になります。
　（なくても問題なく動くアクションがあるかもしれません。アドバイス頂けたら幸いです。）
![Mail merge 画像1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167400/42c2f900-ba62-c330-0686-7560c40900d8.png)
↑図1 Flow全体図


![Mail merge 画像2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1167400/d1d1bb4f-1e04-978b-7e4d-3d6b5b125cee.png)
↑図2 Apply to each
 

#準備するもの
・Excelファイル
　→テーブル（列はメールアドレスさえあればとりあえずOKです。）
・Excelファイルを置くShareponintサイト、またはonedrive
・outlook

#解説
　各アクションを解説していきます。フロー画像の①〜⑤が以下の番号とリンクしています。
　<font color="DeepSkyBlue">*サガンブルー*</font>は各アクションの中にある<font color="DeepSkyBlue">*入力欄*</font>です。

1. **表内に存在する行を一覧表示（旧：複数行の取得）**  
　アクションの名前が変更されているのでご注意を。  
　ここでは、Excelのすべてのテーブル行の値を取得します。対象のExcelシート、テーブルを選択しましょう。   
2. **各変数の初期化**
　1で取得した値を格納する変数を作ります。（初期化＝作る と解釈しています）
　列の数だけ作りましょう。
　　・<font color="DeepSkyBlue">*名前*</font>：テーブル列名と同じにするのをオススメします。
　　・<font color="DeepSkyBlue">*種類*</font>：文字列（数字の場合も文字列に。0を認識します。）
　　・<font color="DeepSkyBlue">*値*</font>：空欄

2. **Aplly to each** 
　ここでは、以下4、5で行う「値の差込作業〜メール送信」が行分終わるまで*組み込み*になります。
　もしかしたら以下のアクションを入れたときに自動に作られるかもしれません。
　　・<font color="DeepSkyBlue">*以下の手順から出力を選択*</font>：Value
　　（**1. 表内に存在する行を一覧表示（旧：複数行の取得）**より）

2. **変数の設定**　in "apply to each" 
　1で得た行の値を2で作成した変数に組み込む作業になります。
　列名＝変数名にしておくと、ひと目で紐付けが分かります。

2. **メールの送信**　in "apply to each" 
　メールを作成しましょう。アドレスや本文に入れたい文字列は変数を挿入しましょう。


　以上で、解説は完了となります。
　念の為、変数に値が代入されているかどうかを必ず確認してから動かしてみてください。確認方法については、**5. メールの送信**の代わりに**Notifications の Send me mobile notification**のテキスト欄に4で得た変数を入れ確認しましょう。

#まとめ
　仕事では、無事に送信することができました。
　ただし、Outlookの機能上、**一斉送信の件数が20件を超えると送信にブレーキが掛かり送信しきれないエラーが起きてしまう**ことがあるそうです。
　詳細はよく分かりませんが、うちではその現象が起きました。
　そのため、**一斉送信で何件まで送ることができるかを確認する**ことをオススメします。


#参考文献
[★Microsoft Flowでメール自動配信をする★](https://qiita.com/g-mwam/items/388c94f55b9bd670f5fc)
CodeDeployの結果をSlackに通知する

AWS Chatbotを使って、CodeDeployの成功/失敗をSlackに通知していきたいと思います。

## AWS Chatbotを設定
AWSマネジメントコンソールからAWS Chatbotをたどり、Slackを指定してチャットクライアントを設定します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/176754a2-2763-8a55-dfa2-0451ad26b51e.png)

### slackへのアクセス権限を付与します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/239427fb-75f6-6e39-9e16-f6834babb30a.png)

### 新しいチャネルを設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/16d8b1a1-ea51-3f32-7469-c9e60217f4d6.png)

* Slackチャネル：プライベートでチャネルIDを指定します

　SlackのチャネルIDは、Slackのチャンネルのリンクをコピーで取得できるURLの末尾が「C」や「G」などで始まる値です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/cb1d6b73-74d7-4d99-9d2a-53dd9b515c22.png)

* アクセス許可：「AWSChatbot-Role」という名前で新規に作ります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/03a28812-8ec1-10ba-1a46-5b1914274aad.png)

### Slack側でメッセージを受け取れるようにする
* AWSマネジメントコンソールからAWS Chatbotを開き、「テストメッセージを送信」を行うと、以下のように、AWS Chatbotアプリ(「`@aws`」)がSlackチャンネルに追加されていること　と記載があります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/b08a2a8c-c6ba-fb04-37f8-0c61e3249b6e.png)

* Slackのチャネルに追加します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/50ed212a-ce46-4d49-7abe-89944ccfceee.png)

## CodeDeployの通知を設定
AWSマネジメントコンソールからCodeDeplopyをたどり、通知ルールの作成を行います

### 通知ルールの作成
先ほど作成した、AWS Chatbot(Slack)を選択し、通知ルールを作成します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/c782a719-f476-7d8d-3b19-f9900785df7b.png)

## 結果イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/5d8e1221-5832-ab6d-3c1e-bdd79c13a6b5.png)

通知されました。
メンションが仕方がわからなかったので、このSlackチャンネルについては全てのメッセージを通知するモードにしました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/ed08dd7f-ec6f-28c4-8c3c-d8c001b53c9a.png)
「Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment」の解決

cdk deployを実行して「Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment」のエラーが発生した場合の解決策の一つとして記載します。

### 前提条件
* Ubuntu 18.04.4 LTS(WSLの利用)

### cdk deploy --profile xxx を実行すると Unable to resolve～エラー

```bash
$ cdk deploy --profile xxx
Unable to resolve AWS account to use. It must be either configured when you define your CDK or through the environment
```

* ~/.aws/configを確認する

```bash:~/.aws/config
$ cat ~/.aws/config 
[profile xxx]
region = ap-northeast-1
[default]
region = ap-northeast-1
[xxx]
region = ap-northeast-1
```

* [profile xxx]を削除する

```bash:~/.aws/config
$ cat ~/.aws/config 
[default]
region = ap-northeast-1
[xxx]
region = ap-northeast-1
```

* cdk deployの再実行

```bash
$ cdk deploy --profile xxx
CdkXXXXXXXStack: deploying...
CdkXXXXXXXStack: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (3/3)

 ✅  CdkDynamodbStack

Stack ARN:
arn:aws:cloudformation:ap-northeast-1:XXXXXXXXXXXX:stack/CdkXXXXXXXStack/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
```

解決
AWS CDKでDynamoDBを作る

cdkの入門として、シンプルにDynamoDBを1テーブルを作っていく流れを書きます
テーブル名はtasksとします


## はじめに
* Ubuntu 18.04.4 LTS (WSL利用)
* VSCode
* aws-cdk 1.94.1
* typescript

## AWS CDKをインストール
```bash
$ npm install -g aws-cdk
$ cdk --version
```

## AWS CDKのプロジェクト作成
```bash
# プロジェクトディレクトリを作成
$ mkdir cdk-dynamodb

# 移動
$ cd cdk-dynamodb/

# プロジェクト作成
$ cdk init app --language=typescript
```

## パッケージインストール
```bash
$ npm install @aws-cdk/aws-dynamodb
```
## DynamoDBを作るコードを書く
taskというテーブル名のDynamoDBを作ります
プロジェクト作成時にひな形が作られているので、そこに肉付けする感じとなります

```ts:/lib/cdk-dynamodb-stack.ts
import * as cdk from '@aws-cdk/core';
import dynamodb = require("@aws-cdk/aws-dynamodb");

export class CdkDynamodbStack extends cdk.Stack {
  public readonly taskTable: dynamodb.Table;
  
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Setup Task Table
    this.taskTable = this.setupTaskTable();
  }

  private setupTaskTable() {
    return new dynamodb.Table(this, "TaskTable", {
      tableName: "tasks",
      removalPolicy: cdk.RemovalPolicy.DESTROY,
      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,
      partitionKey: {
        name: "id",
        type: dynamodb.AttributeType.STRING
      },
      stream: dynamodb.StreamViewType.NEW_AND_OLD_IMAGES
    });
  }
}
```

## DynamoDBを作るコードに対するテストコードを書く
テストコードを書きます

```ts:/test/cdk-dynamodb.test.ts
import { expect as expectCDK, haveResource } from '@aws-cdk/assert';
import * as cdk from '@aws-cdk/core';
import * as CdkDynamodb from '../lib/cdk-dynamodb-stack';

test('DynamoDB Table Created', () => {
    const app = new cdk.App();
    // WHEN
    const stack = new CdkDynamodb.CdkDynamodbStack(app, 'MyTestStack');
    // THEN
    expectCDK(stack).to(haveResource('AWS::DynamoDB::Table', {
      TableName: "tasks"
    }));
});

```

## デプロイ前にテスト
作成したコードをテストします

```bash
$ npm run build && npm test

> cdk-dynamodb@0.1.0 build /home/xxx/cdk-dynamodb
> tsc


> cdk-dynamodb@0.1.0 test /home/xxx/cdk-dynamodb
> jest

 PASS  test/cdk-dynamodb.test.ts (13.729 s)
  ✓ DynamoDB Table Created (140 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        27.174 s
Ran all test suites.
```
無事通りました

## AWSにデプロイ
作成したコードをAWSにデプロイします

```bash
$ cdk deploy --profile xxx
CdkDynamodbStack: deploying...
CdkDynamodbStack: creating CloudFormation changeset...
[██████████████████████████████████████████████████████████] (3/3)

 ✅  CdkDynamodbStack

Stack ARN:
arn:aws:cloudformation:xxxxxxxxx:xxxxxxxxxxx:stack/CdkDynamodbStack/xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

### CloudFormationで確認
スタックが正常に完了しています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/3d98afb8-837f-f374-88c7-04f1539a83de.png)

### DynamoDBで確認
tasksテーブルが作成されています

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1219565/2732b132-e8c2-7cdc-40fc-e153edc30b97.png)

## AWSから削除
デプロイしたものを削除します

```bash
$ cdk destroy --profile xxx
Are you sure you want to delete: CdkDynamodbStack (y/n)? y
CdkDynamodbStack: destroying...

 ✅  CdkDynamodbStack: destroyed
```

### まとめ
* コードで構築できるので再利用できるし、テストも容易にできるので効率的です
【Fiddler Everyone】 Android端末のブラウザの通信キャプチャの方法

## Android端末でのブラウザの通信をFiddler Everyoneで取得する
####①Fiddler Everyoneを起動する
####②設定のConnectionsを開く
ポートは初期設定のままにし(変更したい場合はしておく)、Allow remote computers to connectにチェックを入れる
![fid_everywhere_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/94320f56-c107-4f2f-7ffb-88bdc1fd2334.jpeg)
SAVEを押すと、ファイアウォールの設定がされていない場合に確認が入るが、アクセスを許可する
#### ③Androidのプロキシ設定を行う
Fiddler Everywhereとandroidのwi-fiを同じに設定する
wi-fiの設定から使用しているwi-fiの設定アイコンを選択
![fid_everywhere_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/24c7991d-fa84-a62f-1e52-d609c06dbde1.jpeg)
次に編集アイコンを選択し、詳細オプションを開きプロキシの設定を行う
![fid_everywhere_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/034c21df-991c-af4c-bdd4-2576f9986895.jpeg)
プロキシは手動を選択する
![fid_everywhere_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/6f6b8dab-883b-147c-9b53-10c20ffdef95.jpeg)
プロキシのホスト名はFiddler EverywhereのPC名(IPアドレス)、プロキシポートはFiddler Everywhereで設定したポートを設定する
![60505.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/79c304a1-0858-bde2-e401-79a3fab9a2e2.jpeg)
この設定で、Androidのブラウザ通信がPCのFiddler Everywhereを介して行われるようになるため通信キャプチャが取得できる
#### ④Fiddler Everywherで発行した証明書をandroid端末でインストールする
③後に、androidのブラウザからhttpsのサイトを開くと、証明書がないため安全ではないということでサイトが表示されない
ブラウザから以下のurlへアクセスすると、
http://ipv4.fiddler:{先ほど確認したポート番号}
モーダルが表示され、証明書の名前を指定することでインストールを完了させる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/612995d5-8f0b-4489-bd91-26cad86ab307.png)
ここまでの作業でandroidOSのブラウザからの通信キャプチャも可能となる.
firebase realtime database でLine的なチャットを実装

## はじめに

realtime database の何が realtime かよく分かってなかったのですが、誰かが更新したデータをクライアント側で **イベントでリアルタイムで受け取れる** と知りましたので早速使ってみました。

※nuxtjs のプロジェクトに機能追加していますのでサンプルコードは nuxtjs 用です。

[小１さんすうゲーム](https://kaku3.github.io/e1-math-plus-10/frontend/dist/)

[Chatソース](https://github.com/kaku3/e1-math-plus-10/blob/master/frontend/components/Chat.vue)

![2021-03-27_18h24_43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/c801cd3e-b203-50f3-a9dc-f3de82a06bc9.png)

## イベント登録～読み込み処理

``` *.ts
// 直近10件を取得
// on : イベント登録。データが更新されるたびに実行
// once : 1回のみ実行

// mount 時にイベント登録しておく

const db = firebase.database()
db.ref(this.room)
  .orderByChild('createdAt')
  .limitToLast(10)
  .on("value", (data) => {
  if(data) {
    const obj = data.val()
    if(obj) {
      this.logs = Object.keys(obj).map(k => {
      const o = obj[k]
      return o
      })
    }
  }
})
```

## データ登録
```　*.ts
postComment() {
  if(!this.comment) {
    return
  }
  if(this.room) {
    // push で登録
    const db = firebase.database()
    db.ref(this.room).push({
      name: this.accountStore.account.name,
      comment: this.comment,
      createdAt: (new Date()).getTime()
    })
  }
  this.comment = ""
}
```

## 認証（ガバガバ）
realtime database は割と課金が発生しやすいと評判なので認証済みユーザーのみ書き込み可能にする。
と言っても、ユーザーデータを保存したくないので匿名ログインで対応する。

* firebaseの管理画面で「匿名」ログインを有効にする
![2021-03-27_18h43_57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/a272f6f9-a298-b680-0fd1-09abb24935ea.png)

* middleware でサラッとログインする

``` middleware/authentication.js
import firebase from '@/plugins/firebase'

// 匿名ログイン
firebase.auth().signInAnonymously()
.catch((error) => {
  console.log(`[error] Can not signin anonymouse (${error.code}:${error.message})`);
})

export default function ({ route, store, redirect }) {
  firebase.auth().onAuthStateChanged((user) => {
    // 本来はログインしてなければログイン画面に飛ばすなどの処理を書く
    // 今回は無条件で匿名ログインするため処理なし
    console.log(user)
  })
}

```

* nuxt.config.js に authentication 処理を追加する

``` nuxt.config.js

  router: {
    base: '/e1-math-plus-10/frontend/dist/',
    middleware: ['authentication'] // ★追加
  },

```

## ルール修正

若干安全ではないですがとりあえず `auth != null`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/e36e488c-e27b-00c5-9290-eb154f566bb8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136165/29f30faf-f1cf-5e09-44b4-deddaf8cb60b.png)


## バッジ処理

バッジでボタンを囲めば、右肩にバッジ表示が出ます。表示条件、表示内容を :content, :value で指定。
vuetify、簡単できれいでいいですね。

```　Chat.vue
    <v-badge
      :content="unreadCount"
      :value="unreadCount"
      bordered
      color="info"
      overlap
      class="toggle-show-icon"
    >
      <v-btn
        fab
        dark
        small
        :color="showIconColor"
        @click="toggleShow()">
        <v-icon>mdi-chat</v-icon>
      </v-btn>
    </v-badge>
```

## おわりに

サラッと説明しましたが以上となります。
DBのスキーマ定義なども不要で、適当にデータ投げ込んで適当に通知されて適当にできる、ってぐらい簡単でした。
MVCに立ち戻って解決

解決にこれほど時間を費やしたことはなかった。
だか自分がいかに勉強不足かわかった。

twitter風のアプリでコメント機能を実装中だった。


（１）最初のエラーメッセージはこのメッセージでした

![20210327-085100.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/8a946e04-c0b3-2d8f-2751-2192d5ede204.png)


（２）投稿したメッセージに対してのコメントなので
必ず投稿内容があり、そのコメントであった。
ここからアソシエーションは必須。
ルーティングについてもネストを行っていました。

routes.rb

```rb
  resources :prototypes do
    resources :comments,   only: :create
  end
```

comment.rb

```rb
class Comment < ApplicationRecord
  belongs_to :prototype
  belongs_to :user
```

コメント受けるviewファイルについても
terataliさんでネストとビューファイルで検索をすると
＞タイトル
[『ネストさせたコントローラのビューのパスが通らないです』](URL "https://teratail.com/questions/330031")
のページにて

「フォームに渡すモデルオブジェクトは 

```rb
<%= form_for([@product, @characteristic])  do |f| %> 
```
のように配列で渡すことでできます」

とありました。

そこで

show.html.erb

```rb
<%= form_with model: [@prototype, @comment], local: true do |f| %>
```

と修正しました。

これで
ルーティング：ネスト
ビューファイル：配列でコントローラにひきわたす準備
できたと思いましたが、またまた同じエラーのまま（ここまでで１１時間（汗））

最終的にはできました。

![20210327-085606.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/0ce6237e-ed2e-bc65-dc03-a543b553c771.png)


解決のまとめ

まずroutesの実装で
１。config-rbにて　→→→→→→→→prototype（tweetページ）とcommentのネスト
２。view show.html.erbにて→[@prototype, @comment]でコメントの受け取り

#抜けているものは？

#MVCの[C]です。

prototypes_controller.rb

```rb
  def show
    @prototype = Prototype.find(params[:id])
  end
```

show.html.rbには
’@prototype’と’@comment’を用意して

そこから受け取る側のprototypes_contoroller
には@prototypeしか用意してなかった。

@commentの受けわす先がなかったために「route error」
なのです

##１。受けて　「viewファイル」　
##２。ルーティング 「config-route.rb」
##３。ここにも同じく仲介者 「viewに対応するcontroller」
##それぞれ対応するprototype comment を２つ用意


初心者ありがちです
Ruby on Railsのローカル環境構築

今までRailsアプリの開発環境は全部Dockerで作ってたけど、雑に作って挙動確認したい時とかにいちいちDockerで環境作るの面倒なので、ローカルにもRailsの環境を作っておく。

## 作るもの
- DBはsqlite
- Rubyのバージョンはrbenvで管理

## 前提
- macOS Catalina 10.15.7
- Homebrewが使える
- シェルはzsh

## rbenvをインストール&セットアップ
```zsh
$ brew install rbenv ruby-build
$ rbenv -v      
rbenv 1.1.2
$ vim ~/.zshrc
```
```rb:.zshrc
eval "$(rbenv init -)"
```
```zsh
$ source ~/.zshrc
```

## Rubyをインストール
```zsh
$ rbenv install --list # インストールすることが可能なRubyのバージョン一覧が表示される
$ rbenv install 2.7.2 # Ruby 2.7.2をインストール
$ rbenv versions # 現在インストールされているRubyのバージョン一覧
$ rbenv global 2.7.2 # 今回インストールしたバージョンのRubyを使用するように設定を変更
$ exec $SHELL -l
$ ruby -v
2.7.2 # 違うバージョンが表示されたら、シェルを再起動して再確認する
```

## Railsをインストール
```zsh
$ gem install rails -v "6.1.3.1"
$ exec $SHELL -l
$ rails -v
Rails 6.1.3.1
```

## Railsアプリを作成、動作確認
```zsh
$ rails new sample_app
$ cd sample_app
$ rails s
```

http://localhost:3000
にアクセスして表示を確認。

## その他
- システムのRuby(Macに元々入ってるRubyを使うと、パーミッションの問題でRailsがインストールできないからrbenvとか使った方が良い)
- `.zshrc`内の記述について
    - `eval`は引数にセットしたコマンドを実行するコマンド
    - ここでは`rbenv init -`を実行している
    - なぜ直接実行せず、evalを通しているのか?
        - rbenv init -の内部の処理で`export`コマンドで環境変数を設定する処理がある
        - シェルスクリプトはサブシェル等で実行されるため、コマンド内で変数をexportしても元のシェルにはなんら影響がない
        - evalを使ってexportすると、元のシェルに環境変数を設定することができる
- rails 6.1.3をインストールしようとしたら、mimemagic関連のエラーが出たから6.1.3.1に変更した

## 参考
- [Rubyの開発環境を用意しよう！ | プログラミングの入門なら基礎から学べるProgate[プロゲート]](https://prog-8.com/docs/ruby-env)
- [Ruby on Railsの環境構築をしてみよう！(macOS) | プログラミングの入門なら基礎から学べるProgate[プロゲート]](https://prog-8.com/docs/rails-env)
- [mimemagicの最新動向 - HackMD](https://hackmd.io/@mametter/mimemagic-info-ja)
- [ruby - XXXenv の初期化時のeval "$(XXXenv init-)"の意味 - スタック・オーバーフロー](https://ja.stackoverflow.com/questions/32043/xxxenv-%E3%81%AE%E5%88%9D%E6%9C%9F%E5%8C%96%E6%99%82%E3%81%AEeval-xxxenv-init-%E3%81%AE%E6%84%8F%E5%91%B3)
【Kotlin】Glideの画像データキャッシュを更新したい

#Glideは同じURLからの読み込みだとキャッシュを利用する
Glideのキャッシュ機能は読み込み回数を減らせて便利です。
しかしサーバーのデータを更新してもURLが同じなら、キャッシュから読み込んじゃうので、更新したデータが反映されずに困ることがあります。
以下に回避方法を2種類記載します。

##回避策１：キャッシュからの読み込みをスキップする

```Kotlin
Glide.with(this)
  .load(url)
  .diskCacheStrategy(DiskCacheStrategy.NONE) //ディスクキャッシュをスキップ
  .skipMemoryCache(true) //メモリキャッシュをスキップ
  .into(view)
```

この方法でキャッシュをスキップして更新されたデータを読み込むことはできます。
しかし元々保存されているキャッシュが更新されるわけではないので、毎回キャッシュをスキップしないと古いデータが表示されてしまします。


##回避策２：キャッシュを全削除する
```Kotlin
//ディスクキャッシュをクリア
//バックグラウンドスレッドで実行する必要がある
Glide.get(applicationContext).clearDiskCache()
```
まずはディスクキャッシュを削除します。
これはバックグラウンドスレッドで実行しないとエラーになります。

```Kotlin
//メモリキャッシュをクリア
//メインスレッド で実行する必要がある
Glide.get(applicationContext).clearMemory()
```
メモリキャッシュを削除します。
これはメインスレッドで実行しないとエラーになります。

スレッドが別れててややこしいですが、私はキャッシュの削除で思い通りの動作が実現しました。
公式リファレンスから検索するショートカット

Firefox などのブラウザでは、アドレス欄にキーワードを入力すると任意の検索エンジン（URLに検索クエリーが含まれるAPIであれば）で検索することができます。

例えば、python の公式リファレンスだと次のように登録します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188794/c24f6ff2-7c7c-d4f5-8ede-16b872a39f7f.png)

`%s` の部分に検索クエリーが入ります。キーワードは自由に設定できます。
検索するときはアドレスバーに `py 検索したい文字列` と入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188794/55752543-ba86-fd6d-24ff-41da32e47288.png)

すると、次のような検索結果のページがすぐに開けます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188794/06d28062-f17b-873c-e64b-64f3c624466a.png)

Firefox の場合、こういうものを登録するには、検索バーを右クリックして「この検索にキーワードを設定」メニューを使うと登録することができます。
ただし、サイトに依っては右クリックしても出て来ない作りの所もあります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1188794/f35b9e0d-0760-be50-008b-c05083c619ab.png)



私がよく使っているものを集めました。

## プログラミング言語
### Python3
`https://docs.python.org/3/search.html?q=%s&check_keywords=yes&area=default`
### Python2
`https://docs.python.org/2/search.html?check_keywords=yes&area=default&q=%s`

### cppreference.com
`https://duckduckgo.com/?sites=cppreference.com&q=%s`
自前の検索エンジンは用意していないようです
### MATLAB
`https://jp.mathworks.com/support/search.html?fq=asset_type_name:documentation&q=%s`

## 電子部品
### 秋月電子通商
`https://akizukidenshi.com/catalog/goods/search.aspx?search=x&keyword=%s`
Shift_JIS のため、日本語は使えません
### マルツオンライン
`https://www.marutsu.co.jp/GoodsListGoodsNameNavi.jsp?sdg=1&display=goodsname&q=%s`

## その他
### Weblio英和辞書
`https://ejje.weblio.jp/content_find?query=%s&searchType=exact`

### 英辞郎 on the web
`https://eow.alc.co.jp/search?q=%s`
input type="range"で入力量の塗りつぶしを自作する

#はじめに
`<input type="range">`をカスタマイズする時に`-webkit-appearance: none;`を適用すると、デフォルトではあった入力量の部分が塗りつぶされなくなるので、今回Vueを使ってこれを解決しました。（jQueryでもJavascriptでもできます）

結論からいうと、`linear-gradient(to right,color x%,color x%)`を使って解決しました。バーの入力量を取得して、全体の何%かをVueで計算して`background`プロパティに適応することで、実現することができました。

次にコードとcodepenによるデモを載せます。
#コードとデモ
html

~~~html
<div id="app">
  <div class="rgb">
    <div class="rgbtext">
      <label for="red">red</label>
      <label for="red">{{ red }}</label>
    </div>
    <input id="red" type="range" min="0" max="255" v-model="red" :style="{background: redBar}">
  </div>
</div>
~~~

css(SCSS)

~~~scss
body{
  margin: 0;
}

.rgb{
  .rgbtext{
    width: 400px;
    margin: 20px 0 10px 0;
    display: flex;
    justify-content: space-between;
  }
  input[type=range]{
    width: 400px;
    height: 10px;
    border-radius: 30px;
    box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2);
    // 選択表示の枠を消す
    outline: 0;
    // ブラウザによる描画を外す
    appearance: none;
    -webkit-appearance: none;
    // ボタンの設定
    &::-webkit-slider-thumb{
      -webkit-appearance: none;
      appearance: none;
      width: 20px;
      height: 20px;
      border-radius: 50%;
      border: 2px solid  #707070;
      background-color: #fff;
      box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2);
    }
  }
}

~~~

javascript(Vue)

~~~javascript
let app = new Vue({
  el: "#app",
  data: {
      red: 100,
  },
  computed: {
      redBar: function() {
          let percent = this.red*100/255;
          return `linear-gradient(to right,red `+ percent +`%,#fff `+ percent +`%)`;
      },
  }
})
~~~

codepen

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="css,result" data-user="Nnohara" data-slug-hash="zYNrXwq" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="zYNrXwq">
  <span>See the Pen <a href="https://codepen.io/Nnohara/pen/zYNrXwq">
  zYNrXwq</a> by 野原直人 (<a href="https://codepen.io/Nnohara">@Nnohara</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


#参考
[CSS3 グラデーション（gradient）の指定⽅法 | CSS Lecture](http://www.css-lecture.com/log/css3/css3-gradient.html)
[HTML5 Range (progress bar) - JSFiddle - Code Playground](https://jsfiddle.net/daltonrenaldo/4zxm7fw0/)
[input type=range タグをカスタマイズするために | g200kg Music & Software](https://www.g200kg.com/archives/2017/12/input-typerange.html)
Fiddler Everyone インストールと初期設定

# 導入目的
windowsOSでネットワークキャプチャー用のツールとしてFiddlerを使っていた。
MacやLinuxの対応版としてFiddler Everywhereをインストールしてみる。
今回はWindows版でインストールし動作確認を行う。

### サイトからダウンロード
公式サイトへアクセスし最新版をダウンロード
(メールアドレスの入力と国の選択が必須)
![fid_everywhere_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/c7440d17-ce98-3de8-0358-5eea42303186.jpeg)

### 実行
ダウンロードしてexeを実行する
![fid_everywhere_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/4a8ad563-9622-08f4-0b5c-41afca93d7a7.jpeg)
![fid_everywhere_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/c898567c-13ac-3a2e-3e64-0fcb0f5a3080.jpeg)

起動するとログインが必要
アカウントを作成しログインする
![fid_everywhere_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/720fe67b-8c55-b4e4-b60b-9e4048df1a76.jpeg)
![fid_everywhere_5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/97e7869c-ffc5-55f8-efe1-81f8fe7edf77.jpeg)

ログイン後は自動でネットワークキャプチャが介されるが、HTTPのみでHTTPSのキャプチャは行われない

#### HTTPSの設定
右上の設定を開くとHTTPSの設定ページになる
Trust root certificateを押し、CAをインストールする
次にCapture HTTPS trafficを選択し保存する
モーダルを閉じるとHTTPSのキャプチャも行われるようになる
![fid_everywhere_6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1035014/67c490db-738c-6bb6-c88e-b0ac09b4bcc9.jpeg)

## まとめ
ダウンロードからキャプチャまでで複雑な設定などないため10分程度でツールを使えるようになる。
Mac/Linux版でのツールインストールやスマホのネットワークキャプチャは次回以降の課題とする。
presenceメソッドってもうちょっとなんとかならないのかな

railsのpresenceメソッドって

```rb
hoge = nil
fuga = hoge.presence || "empty"
```

って感じで`||`がつくオプショナルな形なんだから

```rb
presence_or { value_in_blank }
```
みたいに||もラップしたメソッド化されていれば嬉しいな

実際は

```rb
hoge = nil
fuga = hoge || "empty"
```

の書き方でもやってること同じだけど、hogeがnullableな場合を考慮して`presence`の記法が生まれたと思っている(`hoge.present? ? hoge : "empty"`が冗長だから)。
だったらnilの対処時に多くの場合で`||`でデフォルト値を入れるんだから、考慮してほしかったな。

一応例外があるけど

```rb
hoge = ""

fuga = hoge.presence || "empty" # "empty"
fuga = hoge || "empty" # ""
```

どういう経緯で今の形式になっているかも知らないし調べるのも面倒だからPRなんて投げないけど

# 追記
`presence_or`をデフォルト値が引数になる形で関数化した場合、引数が評価されてしまうとコメントいただきました。
確かにそのとおりで、デフォルト値セットが必要ないときにデフォルト値が評価されてしまいます。デフォルト値が関数の返り値でその関数に副作用があったら、意図せず副作用が発生するので、遅延評価されるブロックの形に修正しました

```rb
def hoge_something
  # userがあろうとなかろうと、login_and_return_userは実行され、userがある場合に不要な副作用が発生する
  login_user = user.presence_or(login_and_return_user) 
  ...
end

def hoge_something
  # userがある場合後者は評価されず関数も実行されない
  login_user = user.presence || login_and_return_user
  ...
end

def login_and_return_user
  user = login
  login_count_increment # 副作用がある操作
  user
end
```
Reactエラー対応備忘録

#起きたエラー（warnig）

-Warning: Invalid DOM property `for`. Did you mean `htmlFor`?

#原因

labelでhtmlタグの属性forをそのまま記載していた。

>誤）

```
<p><label for="contact">お問い合わせ内容</label></p>
<textarea id="contact"/>
```

>正）

```
<p><label htmlFor="contact">お問い合わせ内容</label></p>
<textarea id="contact"/>
```
CentOS8にMacのターミナルからSSH接続する

# 環境
ゲストOS　CentOS (Ver 8.3.2011)
ホストOS　macOS Catalina (Ver 10.15.7)

#初めに

今回は、VirtualBoxにCentOSを導入した際に、ターミナルから操作したかったのでssh接続する方法を備忘録としてまとめました。
間違い等がございましたら教えてください。

参考にしたサイト
https://qiita.com/sango/items/816136188387221f05b3

#CentOSのバージョン確認

- CentOS

````ruby:/etc/redhat-release 
CentOS Linux release 8.3.2011
````

では始めます。

#CentOSにopensshが入っているかの確認
CentOS8ではデフォルトでopensshが入っていることを確認しました。

```
$ yum list installed | grep ssh
libssh.x86_64                                      0.9.4-2.el8                                   @anaconda 
libssh-config.noarch                               0.9.4-2.el8                                   @anaconda 
openssh.x86_64                                     8.0p1-5.el8                                   @anaconda 
openssh-askpass.x86_64                             8.0p1-5.el8                                   @AppStream
openssh-clients.x86_64                             8.0p1-5.el8                                   @anaconda 
openssh-server.x86_64                              8.0p1-5.el8                                   @anaconda 
qemu-kvm-block-ssh.x86_64                          15:4.2.0-34.module_el8.3.0+555+a55c8938       @AppStream
```
#CentOSのIPアドレス確認
```
ip a
```
今回は１：lo1とある方のIPアドレスを用いました

その後、VirtualBoxのネットワークをブリッジアダプターに変更します。

#接続
最後にターミナルから

```
ssh (IPアドレス)
```
と記載してSSH接続できます。
本来はパスワードや鍵で管理するべきでるがプライベートの練習のため上記のやり方で実施しました。
EXISTS(SELECT NULL FROM ~)ってなんなん？

業務で初めて知ったEXISTSの使い方と、
どうしても理解しがたかったSELECT NULL FROM ~についてまとめます。

## EXISTSとは
副問い合わせのレコードが1つでもあれば真(TRUE)、1つもなければ偽(FALSE)を返します。

```
-- 例
SELECT * FROM [Aテーブル]
  WHERE EXISTS(
    SELECT * FROM [Bテーブル]
      WHERE ~
  )
```
副問い合わせでレコードが存在したとき、主問い合わせが実行されます。
副問い合わせでレコードが存在しないとき、主問い合わせは実行されません。

## 今回頭を悩ませたSQL

```
SELECT 〜 FROM [Aテーブル], [Bテーブル], [Cテーブル]
  WHERE EXISTS(
    SELECT NULL FROM [Dテーブル]
      WHERE B.◯◯ = D.××
      AND B.◯◯　= D.△△
      AND C.□□ = 1
  )
```
ざっくりこのような感じです。

SELECT NULLってなに？NULLを取得？

副問い合わせの取得条件は B.◯◯ が NULL でした。
取得条件NULLでNULLのレコードが取得できる？から
副問い合わせのレコードは存在している？

とかトンチンカンなこと考えていました。
調べてもよく分かりませんでした。。

## SELECT NULLって？？
「SELECT NULL」はEXISTSと一緒に使われて
EXISTS(SELECT NULL FROM ~)で、副問い合わせのレコードがあるなら真(TRUE)だそうです。
（正直答えを見てもよく理解できなかった。。）
そのため今回はレコードがないため主問い合わせは実行されないということでした。

## さいごに
もう少しSQLの勉強をするのと、調べる際に英語の記事を避けないように心がけます。

##参考
SELECT NULLの回答
→https://stackoverflow.com/questions/4875745/usage-of-select-null

EXISTSについて
→https://itsakura.com/sql-exists
[JavaScript] 文字列の両端の空白を削除する

#概要
インポートしているCSVの文字列に空白文字があり、取り除きたかった時の方法をメモします。

#実装
`trim()`を使うだけで両端の空白を削除できます。

```.js
let hoge = '　hogehoge　';
console.log(hoge.trim());

 //結果：'hogehoge'
```

先頭文字だけ取り除きたい場合は`trimStart()`で可能です。

```.js
let hoge = '　hogehoge　';
console.log(hoge.trimStart());

 //結果：'hogehoge　'
```

最後文字は`trimEnd()`で

```.js
let hoge = '　hogehoge　';
console.log(hoge.trimEnd());

 //結果：'　hogehoge'
```
discord.jsで音声合成機能を作る


# 今回つくるもの

1.discord 上で読み上げるテキストを指定するコマンドを実行 
2.メッセージから読みあげたいテキストを取得
3.Google の TTSAPI にリクエスト送信 
4.結果を取得
 5.`1`が送信されたチャンネルに結果を送信

# 必要なもの

・@replit/node-fetch(`npm i @replit/node-fetch`)
・stream(`npm i stream`)
・util(`npm i util`)
・discord.js(`npm i discord.js`);
discord.js の実行環境の整備は、ここでは省きます。

# コード

```js
const prefix = "!";
const discord = require("discord.js");
const { createWriteStream } = require("fs");
const { pipeline } = require("stream");
const { promisify } = require("util");
const fetch = require("@replit/node-fetch");
const client = new discord.Client({
  intents: [
    discord.GatewayIntentBits.Guilds,
    discord.GatewayIntentBits.GuildMessages,
    discord.GatewayIntentBits.MessageContent,
  ],
});

client.on(discord.Events.MessageCreate, async (message) => {
  if (message.author.bot) return;
  const args = message.content.slice(prefix.length).trim().split(/ +/g);
  const command = args.shift().toLowerCase();
  if (command == "voicetext") {
    const t = args.join(" ");
    const m = Math.random().toString(36).slice(2, 12);
    const streamPipeline = promisify(pipeline);

    const response = await fetch(
      `https://www.google.com/speech-api/v1/synthesize?text=${encodeURI(
        t
      )}&nc=mpeg&lang=ja&speed=0.5&client=lr-language-tts`
    );

    if (!response.ok)
      throw new Error(`unexpected response ${response.statusText}`);

    await streamPipeline(response.body, createWriteStream(`./voices/${m}.mp3`));
    message.channel.send({ content: "結果:", files: [`voices/${m}.mp3`] });
  }
});
client.login("token");
```

# 結果

`!voicetext <text>`を実行すると、音声合成した結果が返ってきます！
![スクリーンショット 2021-03-27 174757.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660386/3a0bdb97-03b8-166e-cba9-762e5903f95e.png)
Nuxt.jsのライフサイクルの穴

# 自分がハマったこと
Nuxt.jsには様々なライフサイクルがある （[参考記事](https://qiita.com/sukezane/items/059b2d33fa9f46e7eb07)）

主要なライフサイクルメソッドの順序は次の通り
`middleware -> asyncData -> created -> mounted -> beforeDestroy -> destroyed`

しかし、`nuxt-link`等で他のページに移動する（ページA→ページB）際にライフサイクルの順番は
`B.middleware -> B.asyncData -> A.beforeDestroy -> A.destroyed -> B.created -> ...`

のようになり、Aの持つ`destroyed`等が発火される前にBの`middleware`等が発火するので注意。
xigmanasトラブル対応

# OSインストールトラブル
OSダウンロードリンク：https://sourceforge.net/projects/xigmanas/files/
Download Latest Versionと記載されていたのでダウンロードしたけれどよく見たらCD用だったという…
バージョンを指定して入っていくとUSB用のファイルもちゃんとある。

XigmaNAS-x64-LiveCD-12.1.0.4.7091.iso
XigmaNAS-x64-LiveUSB-GPT-12.1.0.4.7091.img.gz
XigmaNAS-x64-LiveUSB-MBR-12.1.0.4.7091.img.gz

私が使用したマザーボードはN3150-ITXで、MBRでないとインストールできなかった。
以前はE35LM1というマザボを使用していたが、そちらはCDでしかインストールできなかった。
相性があるのでいろいろ試すしかない…

USBを使用してインストールするときはUEFIで起動時のデバイスにUSBではなくUEFIを選択する。

```
USB:  8.03
UEFI:  8.03
```

インストールが終わるとよくわからないがloginを求められる

```
Login:root
Pass:xigmanas
```


# windows10でフォルダにアクセスできない
SMB1.0が原因だぁ、とネットに書いてあることが多いけれどxigmanasはSMB3にも対応しているはずなのでそんなことはない。
結果として匿名認証がデフォルトでは無効である事が原因だった。
匿名認証でアクセスしようとしている私も悪いのだけど。
参考リンク：https://www.nedia.ne.jp/blog/2019/04/02/13919
依存関係のある deb ファイルの作り方

ファイル構成

```text
$ tree gitclone_1.0-1_amd64
gitclone_1.0-1_amd64
├── DEBIAN
│   └── control
└── usr
    └── local
        └── bin
            └── gitclone.sh
```

```text:gitclone_1.0-1_amd64/DEBIAN/control
Package: gitclone
Version: 1.0-1
Section: base
Priority: optional
Architecture: amd64
Pre-Depends: git
Maintainer: ekzemplaro <you@email.com>
Description: git clone
 When you need some sunshine, just run this
 small program!
 (the space before each line in the description is important)
```

```bash:gitclone_1.0-1_amd64/usr/local/bin/gitclone.sh
#! /bin/bash
#
echo '*** gitclone.sh *** start ***'
echo 'Mar/26/2021 PM 17:28'
#
cd /tmp
git clone https://github.com/ekzemplaro/storytelling
#
echo '*** gitclone.sh *** end ***'
```

gitclone.sh のファイル属性は 0755 です。

パッケージの作成

```bash
dpkg-deb --build gitclone_1.0-1_amd64
```

パッケージのインストール

```bash
sudo apt install ./gitclone_1.0-1_amd64.deb
```

インストールしている様子

```text
$ sudo apt install ./gitclone_1.0-1_amd64.deb
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Note, selecting 'gitclone' instead of './gitclone_1.0-1_amd64.deb'
The following additional packages will be installed:
  git
Suggested packages:
  git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui gitk
  gitweb git-cvs git-mediawiki git-svn
The following NEW packages will be installed:
  git gitclone
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/4558 kB of archives.
After this operation, 36.5 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 /home/ubuntu/tmp/mar27/gitclone_1.0-1_amd64.deb gitclone amd64 1.0-1 [980 B]
Selecting previously unselected package git.
(Reading database ... 101407 files and directories currently installed.)
Preparing to unpack .../git_1%3a2.25.1-1ubuntu3.1_amd64.deb ...
Unpacking git (1:2.25.1-1ubuntu3.1) ...
Setting up git (1:2.25.1-1ubuntu3.1) ...
Selecting previously unselected package gitclone.
(Reading database ... 102155 files and directories currently installed.)
Preparing to unpack .../mar27/gitclone_1.0-1_amd64.deb ...
Unpacking gitclone (1.0-1) ...
Setting up gitclone (1.0-1) ...
```

削除方法

```bash
sudo apt remove gitclone --purge
```
SQLによるデータベースの操作の知識

#本記事について
プログラミング初心者がSQLに関する知識を学んだので、その備忘録として載せております。

どうかお手柔らかにお願いいたしますm (- -)(_ _)ペコリ

##RDB(relational database)
・データベースのこと。

・MySQLなどのデータベースのこと。データを複数のテーブルとして管理して、テーブルとテーブルの関係を定義し、データの関連性を扱えるようにしているデータベース

##SQL(Structured Query Language)
RDB（データベース）の操作を行うための言語

→Active Record（などのORMのメソッド）はSQLに変換されるため、テーブルの操作が可能。Railsの言語をSQLに変換・翻訳）

##SQLのデータベースやテーブルに対しての命令
・データを定義する「DDL（Data Definition Language）」
・データを操作する「DML（Data Manipulation Language）」
・データを制御する「DCL (Data Control Language)」

・SQL→DB、テーブル（命令）

##DDL（Data Definition Language）　
データを定義する
DBやテーブルを作成する、削除する
DBやテーブル自体をどうするかという定義レベルの部分

##DML（Data Manipulation Language）　
データを操作する
データを探したり、登録したり、更新するなどの操作を行う部分

##DCL （Data Control Language）　
データを制御する
テーブルなどの変更を確定したり、取り消したりなどで制御している部分

##RDBMS（Relational DataBase Management System）
リレーションデータベース（RDB）を管理するための専用ソフトウェア
→DBを管理するプログラム

##SQL文の最後には;をつける
セミコロンがないと->が現れ、まだ続くと認識される。;入力後再度エンターを押す。

rails db:migrateが実行される裏側ではCREATE TABLEというSQL文が動いている

##CREATE　
DBやテーブルを作成できる文

##SHOW　   
DBやテーブルを一覧表示できる文

##DROP　　
DBやテーブルを削除できる文

##USE　　　
使用するDBを選択する文

##ALTER　　
DBやテーブルを編集できる文

##ワイルドカード
すべてのパターンにマッチするもの
特殊記号の一つ
文字の代わりに使うことができる記号のこと

##アスタリスク*
すべてのという意味

##SELECT　
データを取得する句のこと

##INSERT　
テーブルのデータを登録する文のこと

##UPDATE　
テーブルのデータを更新する文のこと

##DELETE　
テーブルのデータを削除する文のこと

##where　
取得できるデータを条件によって制限できる句

##LILE　
文字列検索を行う際に使用できる句

##AND演算子　
複数の条件がすべて正しい場合に、正とすることができる演算子

##OR演算子　
複数の条件のうち、１つ以上満たしたデータを取得する演算子

##NOT演算子　
条件が正しくない場合に正となり、否定形の演算子

##BETWEEN演算子　
上限と下限を設定しその範囲に含まれる場合は正となる演算子

##IN演算子　
１つのカラムに対しリストを指定してカラムの値がそのリストに含まれる時、その式は正になるという演算子

##JOIN　
指定したそれぞれのテーブルの、カラムの値が一致するデータを結合することができる句

##サブクエリ　
ある検索結果（SQL文）を使用して、別のSQL文を実行する仕組み

以上です。
Ruby on Railsでの閉じタグ忘れエラー発生

今までに見たことないエラーのため少し焦りました。

通常Ruby on Railsのエラーであれば


![20210324-202013.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/eada11f2-28ee-77c2-bdac-b4ff6bc9a6a2.png)


こんな感じですが、

今回見たのはこれ

![20210327-171227.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/960935/259c074a-3b44-53bd-9017-0b599985595e.png)



単なる閉じタグ忘れエラーでしたが焦りました。
Laravel8.xで外部制約キーありでNULL許可にする方法

ハマったのでメモ。


## だめな例

```php
$table->foreignId('user_id')->constrained()->nullable();
```

## OKな例

```php
$table->foreignId('user_id')->nullable()->constrained();
```

`constrained`の前に`nullable`を入れないとだめでした。ものすごくハマりました。

最初下記を参考にしましたが、8.xではだめだったので、どこかのタイミングで仕様が変わったんでしょうかね。

PHP - laravel nullを許容する外部キーを作成できるのか？｜teratail
https://teratail.com/questions/298892


## 参考

php - Laravel Database Schema, Nullable Foreign - Stack Overflow
https://stackoverflow.com/questions/37735055/laravel-database-schema-nullable-foreign

PHP - laravel nullを許容する外部キーを作成できるのか？｜teratail
https://teratail.com/questions/298892
JIRAトランジションIDの調べ方

# トランジションとは
JIRAの課題がボード上でどのような動きができるかどうかを設定するのがワークフローです。

該当プロジェクトに移動
↓
`プロジェクト設定`をクリック
↓
`ワークフロー`をクリック
↓
`ダイアグラム`をクリックすると、
長方形と矢印で表現されたワークフローが見れます。
<br>この長方形が`ステータス`で、矢印が`トランジション`を示してます。
<br>トランジションとは、**各ステータス間の移動のこと**です。
<br>各`ステータス`と`トランジション`には、IDが振られており、課題のIDが変わると、その課題のボード上の位置も変わります。
![ワークフロー](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1227763/e91cc064-c0dd-053c-9590-568df0969cbc.png)

# トランジションIDの調べ方
前提として、管理画面へのアクセス権があるアカウントが必要。

該当プロジェクトに移動
↓
`プロジェクト設定`をクリック
↓
`ワークフロー`をクリック
↓
該当のワークフローの`アクション`(鉛筆アイコン)をクリック
↓
`テキスト`タブをクリック
↓
`トランジション(ID)`列をチェック
<br>(ID)の部分がトランジションID。
（例）`Backlog(11)`の場合、BacklogのトランジションIDは`11`。
Bootstrapを使って楽します

#【Bootstrapを使って楽します】

私はバックエンドエンジニア志望なのでフロント部分は妥協しようと思います。
最新のBootstrap4を使用します。
バックエンド技術を学ぶことを優先させるためです。
Bootstrapを簡単に調べたので、自分なりの備忘録です。

##Bootstrap

<strong>フロントエンド開発を効率よく行うためのフロントエンドフレームワーク</strong>

HTML, CSS, JavaScriptで制作されている。
レスポンシブ対応のWebサイトのレイアウトを簡単に素早くできる。モバイルにも対応。
　→　CSSフレームワークとも呼ばれる。

よく使われるレイアウトやUIコンポーネントが用意されている。

　※Twitter bootstrap。Twitterのサイト構築に利用されていた。

##Bootstrapを使うことによるメリット

アプリケーション全体を素早く構築できる。
　→　フロントエンド部分の開発時間を短縮できる。
　→　フロント部分を素早く構築する事で、バックエンド部分の構築に時間を割くことができる。

（バックエンドエンジニアを目指しているため、そちらの技術を深く学ぶ必要があるため。）

##Bootstrapを使うことによるデメリット？

ポートフォリオのフロント部分が似たり寄ったりのデザインになりがち。
　→ バックエンドエンジニア志望なので大きなデメリットにはならないと考えている。

　※ただし、その代わりにバックエンドの構築部分で自分の勉強の成果を出していく。
Docker Comporse 基本

#基本操作

```
#イメージのビルド
docker-compose build

#コンテナの作成と起動
docker-compose up -d

#コンテナを停止・削除
docker-compose down

#コンテナの一覧を表示
docker-compose ps

#ログを表示
docker-compose logs

#コンテナを作成してコマンド実行
docker-compose run <サービス> <コマンド>

#起動中のコンテナにコマンド実行
docker-compose exec <サービス> <コマンド>

#バッシュに入る
docker-compose exec app bash
```

#全体の流れ
Docker関連のファイルを用意
初期設定
起動
追加操作

GemfileやDockerfileの内容を変更したとき

```
docker-compose build
docker-compose up -d
```
React.jsのuseState(), 及びステートフック

react-calendarというライブラリを導入したのですが、公式で紹介されているUsageが全く意味がわからなかったので読み解くと、React.jsのステートフックという機能を理解していないことがわかりました。
ここでは、備忘録として、ステートフックだけではなくそれを使用するために私が学んだ周辺知識と併せて書きます。
＜参考＞
　-ステートフックの公式：https://ja.reactjs.org/docs/hooks-state.html

#関数コンポーネントの存在を受け入れる
私は今まで、以下のようにクラスで定義（？）したコンポーネントのみを扱ってきました。

```javascript:react.js
//クラスでコンポーネントを定義
class Example extends React.Component {
  // ...

  render() {
   //JSX
  }
```
しかし、ステートフックとは、クラスを使用しないでコンポーネントを定義する、「関数コンポーネント」にて使用されるものです。

```javascript:react.js
//関数コンポーネント
const Example = (props) => {
  // ...

  return(
  //JSX
  );
}
```

#useState()を使ってState変数を宣言する

クラスで定義したコンポーネントでは、以下のようにstate変数を宣言することには馴染みがあります。

```javascript:react.js
class Example extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0    //state変数の例
    };
  }
```

関数コンポーネントでは、以下のようにステートフックをつかってstate変数を宣言します。

```javascript:react.js
function Example() {
  const [count, setCount] = useState(0);
  // const [state変数名, set変数名] = useState(state変数の初期値)

```

const [count, setCount] = 〇〇　という書き方は、
JSの「分割代入」という書き方とのこと。
 -分割代入：https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment

この書き方により、変数countには初期値の「0」が、SetCountにはcountを更新する際の関数
が代入されているようです（認識あってますか？）

#stateの読み出しと更新
stateの読み出しと更新についても、クラスのコンポーネントと関数コンポーネントを比較します。
「Click me」というボタンをクリックすると、「You clicked {回数} times」という文字列が表示されるJSXを返すことを例にします。

クラスで定義したコンポーネントでは、以下のようにthis.state.変数名で読み出し、
this.setState({変数名: ...})で更新します。

```javascript:react.js
//読み出し   
  <p>You clicked {this.state.count} times</p>

//更新
  <button onClick={() => this.setState({ count: this.state.count + 1 })}>
    Click me
  </button>
```

関数コンポーネントでは、thisは不要です。最初に定義した変数名countと、setCountを使って、よりシンプルに記載できます。

```javascript:react.js
//読み出し   
  <p>You clicked {count} times</p>

//更新
  <button onClick={() => setCount(count + 1)}>
    Click me
  </button>
```
[Linux]awkの使い方① awkって何～？

#はじめに
awkはLinuxの端末で、データベースなんかをちょっと成形したりするときによく使うので、自分の勉強も兼ねて記事を書こうと思いました。

##そもそもawkとは
そもそもawkって何なんだろうと、よくもわからずコマンドを使っていましたので、少しググってみました。
以下引用です。
>awk（オーク）コマンドとは？
　「awk」は空白などで区切られたテキストを処理するコマンドです。演算機能もあり、プログラミング言語としても使用されています。
　Linux環境で使用されているのは、**GNUプロジェクト**による**「gawk」**コマンドが多く、例えばCentOS 7の場合、awkは**/usr/bin/gawk**への**シンボリックリンク**となっています。

以下、引用元

https://www.atmarkit.co.jp/ait/articles/1706/15/news021.html#:~:text=%E3%80%8Cawk%E3%80%8D%E3%81%AF%E7%A9%BA%E7%99%BD%E3%81%AA%E3%81%A9%E3%81%A7,%E3%83%AA%E3%83%B3%E3%82%AF%E3%81%A8%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

##インフォマティクス超初心者の私にはわからなかった単語
* GNUプロジェクト
* gawk
* /usr/bin/gawk
* シンボリックリンク

*一つ調べると、こんな感じで分かんないことだらけで理解するのにめっちゃ時間がかかってしまい、途中で挫折するのがオチなのです。

###GNUプロジェクト
巷でよく聞く「グニュー」というやつか、と思いググってみると以下のような感じ。
>GNUとは、フリーソフトウェア（特に、オープンソースソフトウェア）のみでUNIX風のOSと関連するソフトウェア群を開発・公開するプロジェクト。リチャード・ストールマン（Richard M. Stallman）氏が創始し、同氏が代表を務めるフリーソフトウェア財団（FSF：Free Software Foundation）が推進している。

5割くらいしか理解できていないが、要するにフリーなソフトを出してくれている人たちと理解しました。

https://e-words.jp/w/GNU.html

###gawk
awkに何やらgがついているが、一応調べてみると以下の記載があったので、とりあえずawkと同じだと理解。
> awkがオリジナルのもので、gawkがGNU 独自の拡張を行ったもの
gawkがインストールされていればgawkを使っていれば問題ない

http://beginprogram.blog114.fc2.com/blog-entry-22.html


##/usr/bin/gawkとシンボリックリンク
/usr/bin/gawkと書いてあったので、実際に自分の環境内のこのパスのファイルを見てみる。
すると確かに、/usr/bin/のフォルダ内にgawkのファイルを発見！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1153624/48d1ba9b-f74a-3701-bc5a-e619bacb92b4.png)
そしてシンボリックリンクというのは、要するにショートカットだと思えばいいです。/usr/bin/gawkのファイルにawkという名前のショートカットを作成して、実行しているような感じだと理解しました！

#どんなことができるのか
私の場合は、100万行くらいあるデータベースを、条件にあう行とか必要な列だけを取ってきたり、各行の1列目に同じ文字を付与したりとか。簡単にできちゃうのでお勧めです。


#具体例(少し私の専門的な話になるので読みたい人だけ)
私の場合以下のようなデータをよく扱うので、こちらを参考に少し説明。

【具体例】

```java:sample.vcf
20 14370 rs6054257 G A 29 PASS NS=3;DP=14;AF=0.5;DB;H2 GT:GQ:DP:HQ 0|0:48:1:51,51 1|0:48:8:51,51 1/1:43:5:.,.
20 17330 . T A 3 q10 NS=3;DP=11;AF=0.017 GT:GQ:DP:HQ 0|0:49:3:58,50 0|1:3:5:65,3 0/0:41:3
20 1110696 rs6040355 A G,T 67 PASS NS=2;DP=10;AF=0.333,0.667;AA=T;DB GT:GQ:DP:HQ 1|2:21:6:23,27 2|1:2:0:18,2 2/2:35:4
20 1230237 . T . 47 PASS NS=3;DP=13;AA=T GT:GQ:DP:HQ 0|0:54:7:56,60 0|0:48:4:51,51 0/0:61:2
```

上記のファイルはvcfっていうフォーマットで記述されていて、要するに遺伝子変異の情報を1行1行記述しているものです。
それぞれの列の意味は以下のような感じ。
　1列目の20：染色体20番という意味
　2列目の14370：端から数えた時の染色体上の位置(14370番目の塩基)
　3列目はIDなので無視
　4列目のG：リファレンスとなっている配列の染色体20番14370番目の塩基
　5列目のA：染色体20番14370番目の塩基がどの塩基に変異しているか
　それ以降の列はこの変異に関数る色んな情報が載ってるだけなので無視

上記のファイルを扱うときに、無駄な情報が多くて見にくいので、1~5列目だけに絞ったりとか、1列目にchr(染色体って意味)ってついてないとソフトが読み込まなかったりとか、色々不都合があるので、awkで以下のように成形できます。

```java:awkコマンド
awk '{print "chr"$1,$2,$3,$4,$5}' sample.vcf
```

```java:出力結果
chr20 14370 rs6054257 G A
chr20 17330 . T A
chr20 1110696 rs6040355 A G,T
chr20 1230237 . T .
```

今回の場合は4行しかないので正直手作業とかエクセルの方が速いですが、実際は100万行くらいにあるので、そんなときに非常に便利です。

#次回
次回からawkの使い方について、基礎的なところから少しずつ紹介していけたらと思います。
さくらVPSのDebianを日本語109キーボード化

# さくらVPSのDebianを日本語109キーボード化
さくらVPSの標準OSにはDebianがありませんが、カスタムでDebianをインストールした後、キーボードレイアウトを日本語109にする方法です。

[さくらのVPS（仮想専用サーバー）] (https://vps.sakura.ad.jp/)

最近の日本語ブログ等々いろいろ検索した結果、ようやくこちらのStackExchange superuserの2013年の記事の方法で成功しました。

[Permanently change default language and keyboard settings - what am I missing?
- StackExchange superuser](https://superuser.com/questions/646425/permanently-change-default-language-and-keyboard-settings-what-am-i-missing)

## 環境情報
Debian 10.8 (AMD64)

## 方法
OSインストール完了後、さくらVPSコンソールからVNCコンソールを利用してサーバーに接続、先ずはapt update、apt upgradeを実行して各種モジュールを最新化。

その後、以下を実行。

```
apt install console-data
```

CUIで設定画面が表示されるが、そのまま\<Ok\>を選択。
次に以下を実行。

```
apt install console-setup
```

次の画面が表示されるのでOtherを選択、[Tab]キーで\<Ok\>に移動して[Enter]
![DebianConsoleSetup20210327.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98298/14795d64-97c5-edfc-35b3-db8cceab8626.jpeg)

次の画面でJapaneseを選択、[Tab]キーで\<Ok\>に移動して[Enter]
![DebianConsoleSetup20210327b.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98298/a83721e8-aeaa-c964-2b72-28395e389e3c.jpeg)

次の画面でJapanese (OADG 109A)を選択し、[Tab]キーで\<Ok\>に移動して[Enter]
![DebianConsoleSetup20210327c.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98298/386358fa-4e88-4747-cb9b-c4aacc93d441.jpeg)

これでキーボードレイアウトが日本語109になり、フォントも日本語フォントになったはず。
![DebianConsoleSetup20210327d.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98298/fac4fc40-8674-087a-5793-e6dcb4d4e521.jpeg)

再起動してrootでログインしなおします。

OS初期設定時のrootのパスワードを設定したときはUSキーボードなので、パスワードに記号を使っていると、rootのパスワードが通らないというトラブルが起こりがちです。落ち着いて日本語キーボードとのレイアウトの違いを見くらべて、パスワードの記号を置き換えてログインしましょう。

## 失敗した方法
ネットで見つけた多くの記事には dpkg-reconfigure keyboard-configuration コマンドを実行すればよいとありましたが、下図のように該当するパッケージがないというエラーになりました。
![DebianConsoleSetup20210327e.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/98298/bd83f9fe-243f-f847-87c8-daa1b918958c.jpeg)

## 日本語環境化
個人的に言語設定そのものの日本語化は不要だったため、ここまでです。

### 以上
Web系で働くために抑えておきたいCI/CDパイプライン

#【Web系で働くために抑えておきたいCI/CDパイプライン】

Web系企業でサービス思考でアプリ開発することを目指しています。
CI/CDパイプラインは必須の知識だと思うので理解するために学びました。
AWSの学習にも出てくるので良い機会になります。

##CI（継続的インテグレーション / Continuous Integration）

ソースコードを継続的にチェックインし、ビルドとテストを自動化して、コードを検証する。
プログラムを頻繁に更新し、コンパイルやテストなど定型作業を自動化する。

人の手によるミスの発生や時間のかかりすぎを回避する。
　→ 作業に集中することが可能になる。
　→ 素早くソースコードを開発出来る。

※チェックインする：ソースコードを開発し、リポジトリに新規に登録、変更して更新することなど。

##CD（継続的デプロイメント、 継続的デリバリー / Continuous Deployment、 Continuous Delivery）

開発、更新したソースコードが本番環境で安全に使える状態に反映される。
テスト環境へのデプロイ、本番環境へのデプロイ、リリースまでを自動化する。

デプロイが頻繁に発生しても、ボトルネックや遅延、リスクの原因にならないようにする。

##近年、CI/CDは重要視されている。

アジャイル開発のプラクティスの浸透と進化によって、自動化テストの重要性が高まっている。
（アジャイル開発はスピードが重要）

システムの品質に対する要求も高くなっているため、今まで手動でテストしていたものを自動化テストすることが標準になってきている。

##CI/CDパイプラインのメリット

自動テストによって、人間のミスを検知しやすくなる。
全体的なコーディング量が増えたとしても、後々のエラーを減らす事が出来る。
　→ トータルコストの削減に繋がる。

Sierではウォーターフォール型開発が主流なのかなと個人的に感じている。
テストの自動化の意識はまだまだ低いと思われる。
（ ※Sierで勤務している私の推測範囲のお話です。）

##テスト、ビルド、デプロイを自動化

テストの自動化：エラーの自動チェック、既存機能による影響チェック
ビルドの自動化：ソフトウェアを実行可能な状態にパッケージングする工数を削減
デプロイの自動化：パッケージをサーバーに配備して利用可能な状態に整える工数を削減
シェルスクリプトでCSVファイルを1行ずつ読み込んで処理する

## 実現したいこと

・シェルスクリプトでCSVファイルを1行ずつ読み込む
・各行のカラムを取り出して処理する
・処理結果を別のCSVファイルとして出力する


## 具体的な要件

・以下のようなCSVファイル(input.csv)を読み込む

```txt
1,hoge,hoge,unko
2,hoge,hoge,hoge
3,hoge,hoge,hoge
4,hoge,hoge,unko
5,hoge,hoge,hoge
6,hoge,hoge,hoge
7,hoge,hoge,unko
8,hoge,hoge,hoge
9,hoge,hoge,hoge
10,hoge,hoge,unko
```

・4カラム目が「unko」である行のみ取り出し、別ファイル(output.csv)に出力する


## 実装例

```sh

#!/bin/bash

INPUTFILE="/tmp/input.csv"
OUTPUTFILE="/tmp/output.csv"

# ファイルを読み込む
while read -r LINE
do
  # 読み込み行の4カラム目の値を取り出す
  FOURTHCOLUMN=$(echo "${LINE}" | cut -d ',' -f4)

  # カラムの値が「unko」である場合、出力ファイルに書き込む
  if [ "${FOURTHCOLUMN}" = "unko" ]; then
    echo "${LINE}" >> "${OUTPUTFILE}"
  fi
done < "${INPUTFILE}"

```


このスクリプトを実行すると以下の出力ファイルが得られます。

```output.csv
1,hoge,hoge,unko
4,hoge,hoge,unko
7,hoge,hoge,unko
10,hoge,hoge,unko
```