ディレクトリとファイルの作成、削除、移動、コピーに関するコマンド

# 参考書籍
[新しいLinuxの教科書](https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E/dp/4797380942/ref=sr_1_1?adgrpid=117229375656&hvadid=655144332605&hvdev=c&hvqmt=e&hvtargid=kwd-1152146940662&hydadcr=21814_13461165&jp-ad-ap=0&keywords=%E6%96%B0%E3%81%97%E3%81%84linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8&qid=1688622508&sr=8-1)

# 動作環境
+ Windows11
+ Oracle VM VirtualBox
+ CentOS 7


# ディレクトリ作成

+ 新しくディレクトリを作成するには**mkdir**コマンドを使用する。
+ 存在しない親ディレクトリも含めてディレクトリを作成する際は`-p`オプションを指定する。

### 書式
`mkdir` [オプション] <作成するディレクトリ名>

#### 使用例
~~~bash:workという名前のディレクトリを作成
$ mkdir work
$ ls -F
work/
~~~

~~~bash:深いディレクトリを一気に作成
$ mkdir -p ./work/2023/07
$ ls -F . ./work ./work/2023
.:
work/

./work:
2023/

./work/2023:
07/
~~~

+ 指定したパスの途中のディレクトリが存在しない場合はエラーとなる。
+ Linuxの内部では**ディレクトリはファイルの一種として扱われている**ため、既存のファイル名と同名のディレクトリを作成することはできない。

~~~bash:エラー表示
$ mkdir ./work/2023/07
mkdir: ディレクトリ `./work/2023/07` を作成できません: そのようなファイルやディレクトリはありません

$ mkdir test
mkdir: ディレクトリ `test` を作成できません: ファイルが存在します
~~~

:::note warn
ディレクトリ名は基本的に英語で作成する。
日本語のディレクトリは文字化けなど様々な問題が発生する可能性があるからである。
:::

# ファイル作成

+ Linuxでファイルを作成する方法は複数存在する。
+ **touch**コマンドは中身が何も書かれていない空のファイルを作成する。
+ 複数のファイルをまとめて作成することもできる。
+ 既存のファイル名を指定した場合は**内容が上書きされたり削除されたりしない**。 

### 書式
`touch` <新しいファイル名1> <新しいファイル名2>

#### 使用例
~~~bash:newfileという名前のファイルを作成
$ touch newfile
$ ls 
newfile
~~~

~~~bash:file1とfile2という名前の複数のファイルを作成
$ touch file1 file2
$ ls 
file1 file2
~~~

:::note info
`touch`コマンドの本来の動きはファイルのタイムスタンプ（日時）の更新である。
しかし、指定したファイルが存在しない場合は、新しく空ファイルを作成するという動きをする。
:::


# ファイルとディレクトリの削除

+ ファイルを削除するには**rm**コマンドを使用する。
+ 複数のファイルを一度に削除することもできる。
+ `rm`コマンドでディレクトリを削除するには`-r`オプションを指定する。
+ 削除前に確認を行うには`-i`オプションを指定する

### 書式
`rm` [オプション] <削除するファイル名1> <削除するファイル名2>

#### 使用例

~~~bash:newfileという名前のファイルを削除
$ ls -F
newfile dir/
$ rm newfile
$ ls -F
dir/
~~~

~~~bash:file1とfile2という名前の複数のファイルを削除
$ ls 
file1 file2 file3
$ rm file1 file2
$ ls 
file3
~~~

~~~bash:拡張子が.txtのファイルをまとめて削除
$ rm *.txt
~~~

~~~bash:dirという名前のディレクトリを削除
$ ls -F 
dir/ newfile
$ rm -r dir
$ ls 
newfile
~~~
:::note warn
`-r`オプションがないとエラーとなる。
:::

~~~bash:削除前に確認をさせる
$ rm -ir dir
rm: ディレクトリ `dir` を削除しますか？
~~~
:::note info
ここでYesの意味である`y`もしくは`Y`を入力した後に、Enterキーを押すと削除される。
削除しない場合はNoの意味である`n`もしくは`N`を入力してEnterキーを押す。
:::
:::note warn
`-i`オプションに慣れてしまうと削除対象ファイルの確認がおろそかになる。
LinuxではWindowsやMac OS Xでの**ごみ箱の機能は存在しない**ため、削除対象を事前に確認することが大切である。
:::

## 空のディレクトリの削除
+ 空のディレクトリを削除するには**rmdir**コマンドでも行える。
+ 指定したディレクトリの中にファイルがある場合はエラーとなる。

### 書式
`rmdir` <ディレクトリ名>

#### 使用例

~~~bash:dirという名前のディレクトリを削除
$ ls -F
dir/ newfile
$ rmdir dir
$ ls
newfile
~~~

~~~bash:中身があるディレクトリを指定した場合
$ rmdir dir
rmdir: `dir` を削除できません: ディレクトリは空ではありません
~~~

:::note info
`rmdir`コマンドはファイルが残っていることに気づかずに誤って削除してしまうという事故を防ぐことができる。
:::


# ファイル、ディレクトリのコピー

+ ファイルをコピーするには**cp**コマンドを使用する。
+ `cp`コマンドは**コピー先にファイルが既に存在している場合は上書き**する。
+ 上書き確認をするには`-i`オプションをつける。
+ ディレクトリをコピーするには`-r`オプションをつける。

### 書式
`cp` [オプション] <コピー元>...<コピー先>


+ <コピー先>がディレクトリの場合は、<コピー先>のディレクトリ内に同一ファイル名でコピーする。
+ 複数のファイルをディレクトリにコピーすることもできる。その際は**引数の最後に指定したディレクトリ**へファイルをコピーする。

#### 使用例

~~~bash:file1をfile2という名前でコピー
$ ls 
file1
$ cp file1 file2
$ ls 
file1 file2
~~~

~~~bash:newfileをdirディレクトリへコピー
$ ls -F
dir/ newfile
$ cp newfile dir
$ ls -F . ./dir
.:
dir/ newfile

./dir:
newfile
~~~

~~~bash:複数のファイルをdirディレクトリへコピー
$ ls -F
dir/ file1 file2 file3
$ cp file1 file2 file3 dir
$ ls -F . ./dir
.:
dir/ file1 file2 file3

./dir:
file1 file2 file3

~~~

~~~bash:拡張子txtのファイルをまとめてdirディレクトリへコピー
$ cp *.txt dir
~~~

~~~bash:dir1ディレクトリをdir2という名前でコピー
$ ls -F
dir1/
$ cp -r dir1 dir2
$ ls -F
dir1/ dir2/
~~~

~~~bash:dir2ディレクトリをdir1ディレクトリにコピー
$ ls dir2
file1 file2
$ ls -F
dir1/ dir2/
$ cp -r dir2 dir1
$ ls -F . ./dir1 ./dir1/dir2
.:
dir1/ dir2/

./dir1:
dir2/

./dir1/dir2:
file1 file2
~~~

:::note info
<コピー先>が存在しなければ、<コピー先>に指定した名前でコピーする。
<コピー先>が存在していれば、<コピー先>のディレクトリの中に名前を変えずにコピーする。
:::

:::note warn
ディレクトリのコピーの際は`-r`オプションをつけないとエラーとなる。 
:::

# ファイル、ディレクトリの移動
+ ファイルを移動するには**mv**コマンドを使用する。
+ `cp`コマンドと同様に、複数のファイルを移動することもできる。
+ `cp`コマンドと同様に、**移動先にファイルが既に存在している場合は上書き**する。
+ 上書き確認を行うには`-i`オプションをつける。


### 書式
`mv` [オプション] <移動元>...<移動先>

+ `mv`コマンドは`cp`コマンドと似ていて、移動先がファイルかディレクトリかで動きが変わる。
+ <移動元>と<移動先>の両方にファイル名を指定するとファイル名の変更を行う。
+ <移動先>がディレクトリ名の場合は<移動元>を<移動先>の中へ移動する。

#### 使用例

~~~bash:ファイル名の変更
$ ls
file1 
$ mv file1 file2
$ ls
file2
~~~

~~~bash:ファイルをディレクトリへ移動
$ ls -F 
dir/ newfile
$ mv newfile dir
$ ls -F . ./dir
.:
dir/

./dir:
newfile
~~~

~~~bash:複数ファイルの移動
$ ls -F 
dir/ file1 file2 file3
$ mv file1 file2 file3 dir
$ ls -F . ./dir
.:
dir/

./dir:
file1 file2 file3
~~~

~~~bash:ディレクトリの移動
$ ls -F . ./dir1
.:
dir1/ dir2/

./dir1:
file1 file2
$ mv dir1 dir2
$ ls -F . ./dir2 ./dir2/dir1
.:
dir2/

./dir2:
dir1/

./dir2/dir1:
file1 file2
~~~
:::note info
`cp`コマンドと違い、ディレクトリの移動の際に`-r`オプションを指定する必要はない。
:::



# ファイルの表示
+ ファイルの内容を表示するには**cat**コマンドがよく利用される。
+ 複数のファイルを指定すると、ファイルを連結して表示する。
+ `-n`オプションをつけると行番号をつけて内容を表示する。
+ ファイルを指定しない場合はキーボードからの入力を待つようになる。

### 書式
`cat` [オプション] <ファイル名>


# スクロール表示
+ 行数が長いファイルは内容が1画面に収まりきらなくなる。
+ **less**コマンドは指定したファイルの内容を1画面ごとに表示して、上下にスクロールすることができる。

### 書式
`less` [オプション] <ファイル名>
<br>

<table>
 <caption><code>less</code>コマンドのスクロール操作</caption>
 <thread>
  <tr>
   <th>コマンド</th> <th>内容</th>
  </tr>
 </thread>
  <tr>
   <td>スペースキー、f、Ctrl + v</td> <td>1画面下にスクロールする</td>
  </tr>
  <tr>
   <td>b、Meta + v</td> <td>1画面上にスクロールする</td>
  </tr>
  <tr>
   <td>j、Ctrl + n、Enterキー</td> <td>1行下にスクロールする</td>
  </tr>
  <tr>
   <td>k、Ctrl + p</td> <td>1行上にスクロールする</td>
  </tr>
  <tr>
   <td>q</td> <td>lessコマンドを終了する</td>
  </tr>
</table>

## ファイル内の検索
+ `less`コマンドでファイルを表示中に`/`を入力すると画面の一番下の行が、検索文字列の入力欄に変わる。
+ この`/`の後ろに検索したい文字列を入力してEnterキーを押すと、指定した文字列をファイルの中から検索できる。

<table>
 <caption><code>less</code>コマンドの検索操作</caption>
 <thread>
  <tr>
   <th>コマンド</th> <th>内容</th>
  </tr>
 </thread>
  <tr>
   <td><code>/</code><文字列></td> <td>下方向に向かって検索する</td>
  </tr>
  <tr>
   <td><code>?</code><文字列></td> <td>上方向に向かって検索する</td>
  </tr>
  <tr>
   <td>n</td> <td>次の検索結果に移動する</td>
  </tr>
  <tr>
   <td>N</td> <td>前の検索結果に移動する</td>
  </tr>
</table>

# リンクを張る
+ リンクを張るには**ln**コマンドを使用する。
+ リンクを削除するには`rm`コマンドを使用する。

### 書式
`ln` [オプション] <リンク元ファイル名> <リンク名>

## リンクとは
+ リンクとは**ファイルに別名をつける**Linuxの機能のことである。
+ 別名をつけることを「リンクを張る」と表現する。
+ Windows における「ショートカット」や、Mac OS X における「エイリアス」と似た機能である。
+ リンクには**ハードリンク**と**シンボリックリンク**の2種類がある。

#### 活用方法
リンクは長いパス名を持つファイルやディレクトリを省略する際や、複数バージョンのプログラムを管理する際によく使用される。

### ハードリンク
+ ハードリンクとは**1つのファイルの実態に複数の名前を付ける**機能である。
+ ハードリンクを持つファイルの実態は、**すべてのハードリンクがなくなったときに削除**される。

#### 使用例

~~~bash:ハードリンクfile2を作成
$ ls
file1 
$ ln file1 file2
$ ls 
file1 file2
$ cat file2
......file1の内容が表示される......
~~~

~~~bash:ハードリンクの削除
$ rm file1
$ ls 
file2
$ cat file2
......file1の内容が表示される......
$ rm file2
$ ls
$ 
~~~

:::note info
ハードリンクは複数のファイル名をつける機能のため、ファイルの実体はファイル名が1つでも残っていると削除されない。
:::


### シンボリックリンク
+ シンボリックリンクとは、**リンク先のパス名が書かれた小さな特殊ファイル**である。
+ ハードリンクと異なる主な点は、**ディレクトリに対して作成できる**ことと、**ファイルの実体はリンク先である**ことである。
+ シンボリックリンクを作成するには`-s`オプションを指定する。
+ `ls`コマンドで`-l`オプションを指定すると、リンク先を確認できる。

#### 使用例

~~~bash:シンボリックリンクfile2を作成
$ ls 
file1
$ ln -s file1 file2
$ ls -l
合計 0
-rw-rw-r--. 1 ユーザ名 ユーザ名 0 7月 19 13:05 file1
lrwxrwxrwx. 1 ユーザ名 ユーザ名 5 7月 19 13:05 file2 -> file1
$ cat file2
......file1の内容が表示される......
~~~

~~~bash:シンボリックリンクの削除
$ rm file2
$ ls 
file1
~~~

~~~bash:リンク先を削除
$ ln -s file1 file2
$ ls -l
-rw-rw-r--. 1 ユーザ名 ユーザ名 0 7月 19 13:05 file1
lrwxrwxrwx. 1 ユーザ名 ユーザ名 5 7月 19 13:05 file2 -> file1
$ rm file1
$ ls -l
合計 0
lrwxrwxrwx. 1 ユーザ名 ユーザ名 5 7月 19 13:05 file2 -> file1
$ cat file2
cat: file2: そのようなファイルやディレクトリはありません
~~~

:::note warn
シンボリックリンクを残したまま、リンク先の実体ファイルを削除すると、シンボリックリンクのリンク先がなくなる。
この状態を「リンクが壊れた」状態と呼ぶ。
:::

# ファイルを探す
+ ファイルを探す際は、**find**コマンドと**locate**コマンドの2つがよく使用される。

## findコマンド
### 書式
`find` <検索開始ディレクトリ> <検索条件> <アクション>

+ `find`コマンドを実行すると、<検索開始ディレクトリ>を起点としてディレクトリツリーを順に下りながら、<検索条件>を満たすファイルを探し、<アクション>を実行する。
+ 検索条件を指定しない場合は、**すべてのファイルとディレクトリが対象**となる。
+ アクションを指定しない場合は、`-print`が指定される。`-print`はパス名を表示するアクションである。

#### 検索条件
<dl>
 <dt><code>-name</code> <ファイル名></dt>
 <dd><strong>ファイル名を指定</strong>してファイルを探す際に使用する。</dd>
 <dd>ファイル名の大文字と小文字を区別する。</dd>
 <dd>ファイル名の指定にはワイルドカードとして<code>*</code>と<code>?</code>が使用できる。

 <dt><code>-iname</code> <ファイル名></dt>
 <dd>ファイル名の大文字と小文字を区別しないこと以外は`-name`と同じ動きをする。</dd>

 <dt><code>-type</code> <ファイルタイプ></dt>
 <dd><strong>ファイルの種別を指定</strong>してファイルを探す際に使用する。</dd>
 <dd>指定できるファイルタイプは複数ある。</dd>
</dl>

<table>
 <thread>
  <tr>
   <th>指定</th> <th>ファイル種別</th>
  </tr>
 </thread>
  <tr>
   <td><code>-type f</code></td> <td>通常ファイル</td>
  </tr>
  <tr>
   <td><code>-type d</code><文字列></td> <td>ディレクトリ</td>
  </tr>
  <tr>
   <td><code>-type l</code></td> <td>シンボリックリンク</td>
  </tr>
</table>

+ 検索条件は`-a`で区切る、もしくはスペース区切りで並べることで、複数の検索条件を指定できる。

#### 使用例
~~~bash:file1.txtを検索してパスを表示
$ mkdir -p dir/doc
$ touch file1.txt dir/doc/file1.txt
$ find . -name file1.txt -print
./dir/doc/file1.txt
./file1.txt
~~~

~~~bash:ファイル名の末尾が.txtのファイルを検索
$ find . -name '*.txt' -print
~~~
:::note warn
`-name`で`?`や`*`を使用する際は、bashのパス名展開と解釈されないように`''`（シングルクォート）、もしくは`""`（ダブルクォート）で囲む。
:::
:::note info
`*`などのシェルが解釈する文字をメタ文字と呼ぶ。
:::

~~~bash:カレントディレクトリの下にあるディレクトリを表示
$ find . -type d -print
.
./dir
./dir/doc
~~~

~~~bash:複数の検索条件を指定
$ find . -type f -a -name '*.txt' -print
$ find . -type f -name '*.txt' 
~~~
上記の例では通常ファイルかつ、ファイル名が.txtで終わるファイルのみが表示される。

## locateコマンド
+ `locate`コマンドはパス名の一部を指定してファイルを探すためのコマンドである。
+ `find`コマンドは実行のたびにディレクトリツリーを下って全てのファイルを探すため、時間がかかる場合がある。
+ それに対して、`locate`コマンドは事前にファイルパスのデータベースが作成されていて、実行の際はこの**データベースだけを検索するため高速に動作**する。
+ データベースの更新は一日一回のため、たった今作成したファイルはデータベースに入っていないなど、**最新の状態ではない**ことに注意する。

### 書式、
`locate` [オプション] <検索パターン>

+ オプションに`-i`もしくは`--ignore-case`を指定すると、大文字小文字を区別しない。
+ `-b`もしくは`--basename`を指定すると、ファイル名だけを検索対象にする。
:::note info
`locate`コマンドでは、指定したパターンがファイルパスのどこかに含まれていれば、一致判定となる。
つまり`-b`オプションの指定は、`find`コマンドにおける検索条件の`-name`や`-iname`に該当する。
:::
+ 検索パターンは**複数指定すると OR 検索**となる。
+ AND 検索をするにはオプションに`-A`もしくは`--all`を指定する。

#### 使用例

~~~bash:拡張子.htmlのファイルを検索
$ locate '*.html'
......検索結果......
~~~
:::note info
`find`コマンドと同様にワイルドカードを使用できる。
::: 

~~~bash:拡張子が.htmlもしくはファイル名にdocsを含むファイルを検索
$ locate -b docs '*.html'
......検索結果......
~~~

~~~bash:拡張子が.htmlであり、かつファイル名にdocsを含むファイルを検索
$ locate -A docs '*.html'
......検索結果......
~~~

# 終わりに

次はコマンドの使用方法の検索についてまとめようと思う。

[**次回**](https://qiita.com/sumisumi2000/items/82838800882351b15144)

何かご指摘がありましたら、コメントしていただけると幸いです。
最後までお読みいただきありがとうございました！

[語句補足]: #語句補足