Windowsでシェルスクリプトを書くときの改行コード

Windowsユーザなので、WSLやAmazon Linux上でシェルスクリプトを動かすときに百万回やっています。

# 1.改行コードとは
テキストファイルの各行の最後に存在する、コンピュータに改行することを伝える見えない記号のこと。エディタの設定で可視化することもできる。

Windows、Linux、Macで改行コードが違っているため、Windows上のエディタで書いたスクリプトをWSLなどで動かすと改行コードが理解できずエラーになってしまうことがある。

# 2.事象の再現
Windows 10 のメモ帳を開き、以下シェルスクリプトを作成する。

```shell:windows_newline_code_test.sh
#!/bin/bash/

echo "Windows - newline code test"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/e944fa7e-b551-01f3-37ec-11e55d8429f2.png)


WSLで実行すると、以下エラーになる。

```shell_session
$ bash windows_newline_code_test.bash
windows_newline_code_test.bash: line 2: $'\r': command not found
Windows - newline code test
```

これは Windows の改行コード`CRLF`が使われているために発生するエラー。

# 3.改行コードについて

OS やバージョンによって改行コードが違う。

|OS|名称|コード|
|---|---|---|
|Mac(OS 9 以前)|CR（Carriage Return）|\r|
|unix|LF（Line Feed）|\n|
|Windows|CR+LF（Carriage Return + Line Feed）|\r\n|


## 3-1.改行コードの確認
使用されている改行コードを調べるには `file` コマンドを使用する。

```
file <textfile>
```

### 3-1-1.改行コードが LF の場合
```
$ file lf.txt
lf.txt: UTF-8 Unicode text
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/0209a5a3-e6d8-a6ff-d33c-f09fb5fc5da9.png)

### 3-1-2.改行コードが CR+LF の場合
```
$ file crlf.txt
crlf.txt: UTF-8 Unicode text, with CRLF line terminators
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/f3f18ca6-f5fa-3abf-bf31-0a1913fdb20a.png)


# 4.改行コードの変換

## 4-1.nkf コマンドで変換

`nkf`コマンドで改行コードの変換ができる。私はWSLで利用している Ubuntu に`nkf`コマンドが未インストールだったので、以下コマンドでインストールした。

```
sudo apt install nkf
```

`nkf` コマンドの詳細は以下を参照。

http://manpages.ubuntu.com/manpages/jammy/en/man1/nkf.1.html

改行コードを `LF` に変換するには `nkf` コマンドの `-Lu` (もしくは `-d` ) オプションを使用する。


```shell_session

# 「crlf.txt」の改行コードが CR+LF になっていることを確認する
$ file crlf.txt
crlf.txt: UTF-8 Unicode text, with CRLF line terminators

# 改行コードを LF に変換し、temp.txt に保存
$ nkf -Lu crlf.txt  > temp.txt

# 「temp.txt」の改行コードが LF になっていることを確認する
$ file temp.txt
temp.txt: UTF-8 Unicode text
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/76ad8ad3-e993-8e61-32a6-b618474c1d7e.png)

## 4-2.sed で改行コードを置換する

`sed`で置換することもできる。

```shell_session
# 「crlf.txt」の改行コードが CR+LF になっていることを確認する
$ file crlf.txt
crlf.txt: UTF-8 Unicode text, with CRLF line terminators

# 改行コードを LF に変換する
$ sed -i -e 's/\r//g' crlf.txt

# 「crlf.txt」の改行コードが LF になっていることを確認する
$ file crlf.txt
crlf.txt: UTF-8 Unicode text
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/b1a36c46-6677-e344-e057-f714ad549e77.png)


## 4-2.Visual Studio Code でデフォルト改行コードを変更する
Visual Studio Code（以下、VScode）を開き、[File] - [Preference]- [Settings]で設定画面に遷移する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/b5e304b0-0cc4-8699-9e8e-4686620c7d83.png)
日本語なら[ファイル］-［ユーザ設定］-［設定］で設定画面に遷移できる。

検索バーで「eol」と検索すると、改行の設定「Eol項目」を見つけることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/c0a7b7a9-e2f3-0d16-1c53-690844d11dd6.png)

デフォルトで「auto」になっている。今回はシェルスクリプトを作成したいので、`\n`（LF）を選択する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/cccb4041-1e05-29fd-9544-59051c5f3ff7.png)

VScodeには設定の保存や反映させるボタンなどはなく、これで設定変更が反映されている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/84b980be-bec6-aeb6-eafb-bceee60b13b3.png)

新規ファイル作成すると、右下の改行コード表示が「LF」になっているのが確認できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/25a69e0f-9f0f-7172-4bbc-fdb17861b94e.png)

右下の改行コード表示をクリックして、保存時の改行コードを選択することもできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/24b2a667-93d8-88ed-0a4f-62923441a7d6.png)

### 4-2-1.改行コード変更済Visual Studio Code でシェルスクリプトを作成する

デフォルトの改行コードを変更したVScodeで、以下のようなシェルスクリプトを作成する。

```shell:vscode_newline_code_test.sh
#!/bin/bash/

echo "vscode_newline_code_test"
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1723719/8644260f-9881-e1a6-f7af-07ece33b9e65.png)

実行すると、エラーなく実行されるのが確認できる。

```shell_session
$ bash vscode_newline_code_test.sh
vscode_newline_code_test
```


# 参考

https://qiita.com/roadricefield/items/32d781ed93bd70dded73

https://ja.wikipedia.org/wiki/%E6%94%B9%E8%A1%8C%E3%82%B3%E3%83%BC%E3%83%89

https://shellscript.sunone.me/character_code.html