ファイルとディレクトリの操作
最終更新日:2024-11-22 | ページの編集
概要
質問
- ファイルやディレクトリをどのように作成、コピー、削除できますか?
- ファイルをどのように編集できますか?
目的
- 指定された図に一致するディレクトリ階層を作成する。
- エディターを使用して、または既存のファイルをコピーおよびリネームして、その階層内にファイルを作成する。
- 指定されたファイルやディレクトリを削除、コピー、移動する。
ディレクトリの作成
これまでにファイルやディレクトリを探索する方法を学びましたが、 それらを最初に作成する方法はどうすれば良いでしょうか?
このセクションでは、exercise-data/writing
ディレクトリを例として使用して、
ファイルやディレクトリを作成および移動する方法を学びます。
ステップ1: 現在の場所と既存の内容を確認する
まだDesktop上のshell-lesson-data
ディレクトリ内にいるはずです。
これを確認するには以下を使用します:
出力
/Users/nelle/Desktop/shell-lesson-data
次に、exercise-data/writing
ディレクトリに移動してその内容を確認します:
出力
haiku.txt LittleWomen.txt
ディレクトリを作成する
mkdir thesis
コマンドを使用して、thesis
という名前の新しいディレクトリを作成します
(このコマンドは出力を生成しません)。
名前から想像できるように、
mkdir
は「ディレクトリを作成する」(make
directory)を意味します。 thesis
は相対パスであるため
(つまり、/what/ever/thesis
のようにスラッシュが先頭についていない)、
新しいディレクトリは現在の作業ディレクトリに作成されます:
出力
haiku.txt LittleWomen.txt thesis/
thesis
ディレクトリを作成したばかりなので、中にはまだ何もありません:
mkdir
は1回で単一のディレクトリを作成するだけではありません。
-p
オプションを使用すると、ネストされたサブディレクトリを
1回の操作で作成することができます:
ls
コマンドの-R
オプションは、ディレクトリ内のすべてのネストされたサブディレクトリをリストします。
先ほど作成したproject
ディレクトリの新しいディレクトリ階層を再帰的にリストしてみましょう:
出力
../project/:
data/ results/
../project/data:
../project/results:
同じことを行う2つの方法
シェルを使用してディレクトリを作成することは、
ファイルエクスプローラーを使用することと何ら変わりありません。
オペレーティングシステムのグラフィカルファイルエクスプローラーで現在のディレクトリを開くと、
thesis
ディレクトリがそこにも表示されます。
シェルとファイルエクスプローラーはファイルを操作するための2つの異なる方法ですが、
ファイルやディレクトリ自体は同じものです。
ファイルやディレクトリの良い名前付け
複雑な名前のファイルやディレクトリは、 コマンドラインで作業する際に苦労の原因になります。 ここでは、ファイルやディレクトリ名に関するいくつかの有用なヒントを紹介します。
- スペースを使用しない。
スペースは名前をより意味のあるものにしますが、
スペースはコマンドラインで引数を区切るために使用されるため、
ファイルやディレクトリ名にスペースを使用しない方が良いです。
代わりに-
や_
を使用できます(例:north-pacific-gyre/
の代わりにnorth pacific gyre/
)。
これを試してみるには、mkdir north pacific gyre
を入力して、
ls -F
で作成されたディレクトリを確認してください。
- 名前を
-
(ダッシュ)で始めない。
コマンドは、-
で始まる名前をオプションとして処理します。
- 文字、数字、
.
(ピリオド)、-
(ダッシュ)、および_
(アンダースコア)を使用する。
その他の多くの文字にはコマンドラインで特別な意味があります。 これについては、このレッスンで学びます。 特定の特殊文字を使用すると、コマンドが期待通りに動作しなかったり、 データ損失を引き起こす可能性があります。
スペースやその他の特殊文字を含むファイルやディレクトリの名前を参照する必要がある場合は、
その名前をシングルクオート('
)で囲む必要があります。
詳細はGNUのクオートに関するドキュメントを参照してください。
テキストファイルを作成する
cd
を使用して作業ディレクトリをthesis
に変更し、
nano
というテキストエディタを実行してdraft.txt
というファイルを作成しましょう:
どのエディタを使うべき?
ここで「nano
はテキストエディタです」と言うとき、私たちは本当に「テキスト」を意味します。
それはプレーンな文字データのみを扱うことができ、
表や画像、その他の人間に優しいメディアは扱えません。
私たちはそのシンプルさゆえに例として使用しますが、
そのために十分な機能や柔軟性を欠く可能性があります。
Unixシステム(LinuxやmacOSなど)では、 多くのプログラマーがEmacsや Vim(どちらも学習に時間が必要)、
またはgeditや VScodeなどのグラフィカルエディタを使用します。
Windowsでは、Notepad++を使用することをお勧めします。
Windowsにはnotepad
という組み込みのエディタもあり、このレッスンの目的ではnano
と同様にコマンドラインから実行できます。
どのエディタを使用する場合でも、 それがファイルを検索し保存する場所を知る必要があります。 シェルからエディタを起動すると、 おそらく現在の作業ディレクトリをデフォルトの保存場所として使用します。 コンピュータのスタートメニューを使用する場合は、 デスクトップやドキュメントディレクトリに保存するように求められるかもしれません。 これは、初めて「名前を付けて保存」するときに別のディレクトリに移動することで変更
できます。
Let’s type in a few lines of text.
テキストに満足したら、Ctrl+O
(CtrlまたはControlキーを押しながらOキーを押す)を押して、
データをディスクに書き込みます。テキストを含むファイルの名前を指定するよう求められます。
デフォルトで提案されたdraft.txt
を受け入れるには、Returnを押してください。
ファイルが保存されたら、Ctrl+Xを押してエディタを終了し、 シェルに戻ります。
Control、Ctrl、または^キー
Controlキーは「Ctrl」キーとも呼ばれます。 Controlキーを使用する方法にはさまざまな記述があります。 たとえば、Controlキーを押しながらXキーを押す指示は以下のように記述されることがあります:
Control-X
Control+X
Ctrl-X
Ctrl+X
^X
C-x
nanoでは、画面の下部に^G Get Help ^O WriteOut
と表示されます。
これは、Control-G
でヘルプを表示し、Control-O
でファイルを保存できることを意味します。
nano
は終了後に画面に何も出力しませんが、
ls
を実行するとdraft.txt
というファイルが作成されたことがわかります:
出力
draft.txt
touch
コマンドは、現在のディレクトリにmy_file.txt
という新しいファイルを生成します。 コマンドラインプロンプトでls
を入力すると、この新しく生成されたファイルを確認できます。 また、GUIファイルエクスプローラーでもmy_file.txt
を見ることができます。ls -l
でファイルを調べると、my_file.txt
のサイズは0バイトであることがわかります。 つまり、データが含まれていません。テキストエディタでmy_file.txt
を開くと空白です。一部のプログラムは、出力ファイルを自分で生成するのではなく、 空のファイルが既に生成されていることを要求します。 プログラムが実行されると、既存のファイルを検索し、そこに出力を記録します。
touch
コマンドを使用すると、このようなプログラム用に空のテキストファイルを効率的に生成できます。
名前に何が含まれているのか?
Nelleのすべてのファイルが「何か.何か」という形式の名前であることに気づいたかもしれません。
このレッスンでは常に拡張子.txt
を使用しました。
これは単なる慣例ですが、ファイルをmythesis
やその他ほとんど任意の名前で呼ぶこともできます。
しかし、ほとんどの人は異なる種類のファイルを区別するために、2部構成の名前を使います。
その名前の後半部分はファイル拡張子と呼ばれ、ファイルが保持するデータの種類を示します:
たとえば、.txt
はプレーンテキストファイル、.pdf
はPDFドキュメント、
.cfg
はプログラムのパラメータを含む設定ファイル、.png
はPNG画像などです。
これは重要な慣例に過ぎません。ファイルには単にバイトが含まれるだけで、 そのバイトをプレーンテキストファイル、PDFドキュメント、設定ファイル、画像などのルールに従って解釈するのは私たちとプログラム次第です。
例えば、クジラのPNG画像をwhale.mp3
と名付けても、
それがクジラの歌の録音になるわけではありません。
ただし、オペレーティングシステムがそのファイルを音楽プレーヤーに関連付ける場合があります。
この場合、ファイルエクスプローラーでwhale.mp3
をダブルクリックすると、
音楽プレーヤーが自動的に(そして誤って)そのファイルを開こうとします。
ファイルとディレクトリを移動する
shell-lesson-data/exercise-data/writing
ディレクトリに戻ります:
thesis
ディレクトリにはdraft.txt
というファイルがありますが、
これは特に情報量の多い名前ではありません。
そこで、mv
を使用してファイル名を変更しましょう。
mv
は「move」の略です:
最初の引数は「移動するもの」、2番目の引数は「移動先」を指定します。
この場合、
thesis/draft.txt
をthesis/quotes.txt
に移動しています。
これにより、ファイル名を変更するのと同じ効果が得られます。
ls
を実行すると、
thesis
にはquotes.txt
という1つのファイルが含まれていることがわかります:
出力
quotes.txt
ターゲットファイル名を指定する際は注意が必要です。
mv
は既存のファイルを上書きする場合、警告なしに実行されるため、データ損失につながる可能性があります。
ただし、mv -i
(またはmv --interactive
)オプションを使用すると、
上書きする前に確認を求めるようになります。
なお、mv
はディレクトリにも使用できます。
次に、quotes.txt
を現在の作業ディレクトリに移動します。
再びmv
を使用しますが、
今回は2番目の引数としてディレクトリ名だけを使用し、
ファイル名を保持しつつ別の場所に移動させることを指定します。
(これが「move」と呼ばれる理由です。) この場合、
使用するディレクトリ名は、前述の特殊なディレクトリ名.
です。
この操作により、ファイルは元のディレクトリから現在の作業ディレクトリに移動されます。
ls
を実行すると、thesis
が空であることがわかります:
出力
$
または、quotes.txt
がthesis
ディレクトリに存在しないことを
明示的にリストして確認することもできます:
エラー
ls: cannot access 'thesis/quotes.txt': No such file or directory
ls
にファイル名やディレクトリを引数として指定すると、その指定された
ファイルやディレクトリだけをリストします。
引数として指定したファイルが存在しない場合、
シェルは上記のようにエラーを返します。
これにより、現在のディレクトリにquotes.txt
が存在することを確認できます:
出力
quotes.txt
ファイルとディレクトリをコピーする
cp
コマンドはmv
と非常によく似ていますが、
ファイルを移動するのではなくコピーします。
正しく動作したことを確認するには、
ls
を2つのパスを引数として使用します。
ほとんどのUnixコマンドと同様に、ls
には複数のパスを指定できます:
出力
quotes.txt thesis/quotations.txt
ディレクトリとそのすべての内容をコピーするには、
再帰的なオプション-r
を使用できます。
例えば、ディレクトリをバックアップするには:
結果を確認するために、thesis
ディレクトリとthesis_backup
ディレクトリの内容をリストします:
出力
thesis:
quotations.txt
thesis_backup:
quotations.txt
ディレクトリをコピーする場合、-r
フラグを含めることが重要です。
このオプションを省略すると、ディレクトリが省略されたというメッセージが表示されます:
ファイルのリネーム
現在のディレクトリにデータを分析するために必要な統計テストのリストを含むプレーンテキストファイルを作成し、
statstics.txt
という名前を付けたと仮定します。
ファイルを作成して保存した後で、名前のスペルミスに気付いた場合、 このミスを修正するには以下のコマンドのどれを使用できますか?
cp statstics.txt statistics.txt
mv statstics.txt statistics.txt
mv statstics.txt .
cp statstics.txt .
- いいえ。これにより正しい名前のファイルが作成されますが、 間違った名前のファイルがディレクトリ内に残り、それを削除する必要があります。
- はい。このコマンドを使用するとファイル名を変更できます。
- いいえ。ピリオド(
.
)はファイルの移動先を示しますが、新しいファイル名を提供しません。 同じ名前のファイルは作成できません。 - いいえ。ピリオド(
.
)はファイルのコピー先を示しますが、新しいファイル名を提供しません。 同じ名前のファイルは作成できません。
最初に/Users/jamie/data
ディレクトリにいて、新しいフォルダrecombined
を作成します。
次の行で、mv
コマンドを使用してproteins.dat
ファイルを新しいフォルダrecombined
に移動します。
その後、移動したファイルをコピーします。
ここでのポイントは、ファイルがどこにコピーされたかです。
..
は「1レベル上に移動」を意味するため、コピーされたファイルは/Users/jamie
にあります。
注意すべき点は、..
が現在の作業ディレクトリに基づいて解釈されることであり、
コピー元のファイルの場所には基づいていないということです。
したがって、ls
(/Users/jamie/data
内で実行)で表示されるのはrecombined
フォルダだけです。
- いいえ。説明の通り、
proteins-saved.dat
は/Users/jamie
にあります。 - はい。
- いいえ。説明の通り、
proteins.dat
は/Users/jamie/data/recombined
にあります。 - いいえ。説明の通り、
proteins-saved.dat
は/Users/jamie
にあります。
ファイルとディレクトリの削除
shell-lesson-data/exercise-data/writing
ディレクトリに戻り、
作成したquotes.txt
ファイルを削除して、このディレクトリを整理しましょう。
このために使用するUnixコマンドはrm
(「remove」の略)です:
ファイルが削除されたことを確認するには、ls
を使用します:
エラー
ls: cannot access 'quotes.txt': No such file or directory
削除は永久的です
Unixシェルには削除したファイルを回復するためのゴミ箱がありません (ただし、ほとんどのUnix向けグラフィカルインターフェースにはゴミ箱があります)。 代わりに、ファイルを削除すると、それらはファイルシステムからリンクが解除され、 ディスク上のストレージ領域が再利用できるようになります。 削除されたファイルを見つけて回復するためのツールは存在しますが、 特定の状況で動作する保証はありません。 削除されたファイルのディスクスペースがすぐに再利用される可能性があるためです。
rm
を安全に使用する
rm -i thesis_backup/quotations.txt
を実行するとどうなりますか?
rm
を使用する際に、この保護が必要な理由は何ですか?
出力
rm: remove regular file 'thesis_backup/quotations.txt'? y
-i
オプションは、削除前に確認を求めます(Yで削除を確認、
Nでファイルを保持します)。
Unixシェルにはゴミ箱がないため、一度削除されたファイルは永久に消えます。
-i
オプションを使用することで、
削除するのが本当に必要なファイルだけであることを確認する機会が得られます。
rm
コマンドを使用してthesis
ディレクトリを削除しようとすると、エラーメッセージが表示されます:
エラー
rm: cannot remove 'thesis': Is a directory
これは、rm
がデフォルトではファイルに対してのみ動作し、ディレクトリには動作しないためです。
rm
コマンドは、再帰オプション-r
を使用することで
ディレクトリとその内容をすべて削除できますが、
確認のプロンプトは表示されません:
シェルを使用して削除されたファイルは回復できないため、
rm -r
は慎重に使用する必要があります。
インタラクティブなオプションrm -r -i
を追加することを検討してください。
複数のファイルやディレクトリの操作
複数のファイルを一度にコピーまたは移動する必要がある場合があります。 これは、個別のファイル名のリストを指定するか、 ワイルドカードを使用して命名パターンを指定することで実行できます。 ワイルドカードは、Unixファイルシステムをナビゲートするときに 不明な文字や文字のセットを表すために使用される特殊な文字です。
複数のファイルをコピーする
この演習では、shell-lesson-data/exercise-data
ディレクトリ内でコマンドをテストできます。
以下の例では、複数のファイル名とディレクトリ名が指定された場合、
cp
は何を行いますか?
以下の例では、3つ以上のファイル名が指定された場合、cp
は何を行いますか?
出力
basilisk.dat minotaur.dat unicorn.dat
複数のファイル名に続いてディレクトリ名が指定された場合
(つまり、宛先ディレクトリは最後の引数でなければなりません)、
cp
はファイルを指定されたディレクトリにコピーします。
3つ以上のファイル名が指定された場合、cp
は以下のようなエラーを出します。
これは、cp
が最後の引数をディレクトリ名として期待しているためです。
エラー
cp: target 'basilisk.dat' is not a directory
ワイルドカードを使用して複数のファイルにアクセスする
ワイルドカード
*
はワイルドカードで、0個以上の他の文字を表します。
shell-lesson-data/exercise-data/alkanes
ディレクトリを考えてみましょう:
*.pdb
はethane.pdb
、propane.pdb
、および’.pdb’で終わるすべてのファイルを表します。
一方、p*.pdb
はpentane.pdb
とpropane.pdb
のみを表します。
これは、先頭の’p’がファイル名の最初の文字’p’で始まるものだけを表すためです。
?
もワイルドカードですが、これは正確に1文字を表します。
したがって、?ethane.pdb
はmethane.pdb
を表す可能性があり、
*ethane.pdb
はethane.pdb
とmethane.pdb
の両方を表します。
ワイルドカードは互いに組み合わせて使用できます。たとえば、
???ane.pdb
は3文字に続いてane.pdb
を示し、
cubane.pdb
、ethane.pdb
、octane.pdb
を表します。
シェルがワイルドカードを見ると、それを展開して一致するファイル名のリストを作成し、
コマンドを実行する前に処理します。
例外として、ワイルドカード式が一致するファイルを見つけられなかった場合、
Bashはその式をコマンドにそのまま引数として渡します。
たとえば、alkanes
ディレクトリでls *.pdf
を入力すると、
(.pdb
で終わるファイルしか含まれていない場合)
*.pdf
というファイルが存在しないというエラーメッセージが表示されます。
一般的に、wc
やls
などのコマンドは、これらの式に一致するファイル名のリストを処理しますが、
ワイルドカード自体は処理しません。
ワイルドカードを展開するのはシェルであり、他のプログラムではありません。
パターンに一致するファイル名をリストする
alkanes
ディレクトリで実行すると、どのls
コマンドが次の出力を生成しますか?
ethane.pdb methane.pdb
ls *t*ane.pdb
ls *t?ne.*
ls *t??ne.pdb
ls ethane.*
解答は3.
です。
1.
は、ゼロ個以上の文字(*
)に続いてt
、
さらにゼロ個以上の文字(*
)に続いてane.pdb
を含むすべてのファイルを表示します。
これにはethane.pdb
、methane.pdb
、octane.pdb
、pentane.pdb
が含まれます。
2.
は、ゼロ個以上の文字(*
)に続いてt
、
次に1文字(?
)、ne.
に続いてゼロ個以上の文字(*
)を含むすべてのファイルを表示します。
これによりoctane.pdb
とpentane.pdb
が表示されますが、thane.pdb
で終わるものは一致しません。
3.
は、t
とne
の間に2文字(??
)を含むものを一致させることで、2.
の問題を修正します。
これが正解です。
4.
はethane.
で始まるファイルのみを表示します。
ワイルドカードについてもっと学ぶ
Samは、キャリブレーションデータ、データセット、およびデータセットの説明を含むディレクトリを持っています:
BASH
.
├── 2015-10-23-calibration.txt
├── 2015-10-23-dataset1.txt
├── 2015-10-23-dataset2.txt
├── 2015-10-23-dataset_overview.txt
├── 2015-10-26-calibration.txt
├── 2015-10-26-dataset1.txt
├── 2015-10-26-dataset2.txt
├── 2015-10-26-dataset_overview.txt
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
├── 2015-11-23-dataset_overview.txt
├── backup
│ ├── calibration
│ └── datasets
└── send_to_bob
├── all_datasets_created_on_a_23rd
└── all_november_files
次のフィールド作業に出発する前に、Samはデータをバックアップし、 いくつかのデータセットを同僚のBobに送信したいと考えています。 彼女は以下のコマンドを使用して作業を完了します:
BASH
$ cp *dataset* backup/datasets
$ cp ____calibration____ backup/calibration
$ cp 2015-____-____ send_to_bob/all_november_files/
$ cp ____ send_to_bob/all_datasets_created_on_a_23rd/
空欄を埋めて、Samを手助けしてください。
最終的なディレクトリ構造は以下のようになります:
BASH
.
├── 2015-10-23-calibration.txt
├── 2015-10-23-dataset1.txt
├── 2015-10-23-dataset2.txt
├── 2015-10-23-dataset_overview.txt
├── 2015-10-26-calibration.txt
├── 2015-10-26-dataset1.txt
├── 2015-10-26-dataset2.txt
├── 2015-10-26-dataset_overview.txt
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
├── 2015-11-23-dataset_overview.txt
├── backup
│ ├── calibration
│ │ ├── 2015-10-23-calibration.txt
│ │ ├── 2015-10-26-calibration.txt
│ │ └── 2015-11-23-calibration.txt
│ └── datasets
│ ├── 2015-10-23-dataset1.txt
│ ├── 2015-10-23-dataset2.txt
│ ├── 2015-10-23-dataset_overview.txt
│ ├── 2015-10-26-dataset1.txt
│ ├── 2015-10-26-dataset2.txt
│ ├── 2015-10-26-dataset_overview.txt
│ ├── 2015-11-23-dataset1.txt
│ ├── 2015-11-23-dataset2.txt
│ └── 2015-11-23-dataset_overview.txt
└── send_to_bob
├── all_datasets_created_on_a_23rd
│ ├── 2015-10-23-dataset1.txt
│ ├── 2015-10-23-dataset2.txt
│ ├── 2015-10-23-dataset_overview.txt
│ ├── 2015-11-23-dataset1.txt
│ ├── 2015-11-23-dataset2.txt
│ └── 2015-11-23-dataset_overview.txt
└── all_november_files
├── 2015-11-23-calibration.txt
├── 2015-11-23-dataset1.txt
├── 2015-11-23-dataset2.txt
└── 2015-11-23-dataset_overview.txt
フォルダ構造を再現する
新しい実験を開始するにあたり、以前の実験のディレクトリ構造を複製して、 新しいデータを追加できるようにしたいと考えています。
以前の実験は2016-05-18
というフォルダにあり、この中にはdata
フォルダが含まれています。
さらに、このフォルダにはraw
とprocessed
という名前のフォルダが含まれ、それぞれデータファイルを持っています。
目標は、2016-05-18
フォルダのフォルダ構造を2016-05-20
フォルダにコピーして、
最終的なディレクトリ構造を以下のようにすることです:
出力
2016-05-20/
└── data
├── processed
└── raw
以下のどのコマンドセットがこの目標を達成しますか? 他のコマンドセットは何をするでしょうか?
最初の2つのコマンドセットは、この目標を達成します。 最初のセットは、トップレベルのディレクトリを作成してからサブディレクトリを作成します。
3番目のコマンドセットはエラーになります。
mkdir
のデフォルトの動作では、存在しないディレクトリのサブディレクトリを作成できないためです。
中間レベルのフォルダを最初に作成する必要があります。
4番目のコマンドセットは、この目標を達成します。
-p
オプションを使用すると、必要に応じて中間のサブディレクトリも
作成できます。
最後のコマンドセットでは、raw
とprocessed
ディレクトリがdata
ディレクトリと同じレベルに作成されます。
まとめ
-
cp [old] [new]
はファイルをコピーします。 -
mkdir [path]
は新しいディレクトリを作成します。 -
mv [old] [new]
はファイルまたはディレクトリを移動(リネーム)します。 -
rm [path]
はファイルを削除します。 -
*
はファイル名内で0文字以上の任意の文字に一致します。例えば、*.txt
は.txt
で終わるすべてのファイルに一致します。 -
?
はファイル名内で任意の1文字に一致します。例えば、?.txt
はa.txt
に一致しますが、any.txt
には一致しません。 - Controlキーの使用法は
Ctrl-X
、Control-X
、^X
などさまざまな方法で表現されることがあります。 - シェルにはゴミ箱がありません。一度削除すると、完全に消えます。
- ほとんどのファイル名は
something.extension
の形式です。拡張子は必須ではありませんが、通常ファイル内のデータの種類を示します。 - 作業内容によっては、Nanoよりも強力なテキストエディタが必要になる場合があります。