オタクとしての信用を築きたい場合は、シェル スクリプト シリーズの第 2 回にご参加ください。先週のスクリプトにいくつかの修正、いくつかの改善、および初心者向けのループに関するガイドがあります。
datecp スクリプトの再考
シェル スクリプト ガイドの最初の記事 では、ファイル名の末尾に日付を追加した後、ファイルをバックアップ ディレクトリにコピーするスクリプトを作成しました。
、変数参照を処理するもっと良い方法があるとコメントで指摘しました。
![]()
bash シェルでは引数はスペースで区切られ、展開されたコマンドの結果にスペースが含まれる場合はトークン化されます。あなたのスクリプトでは、
cp $1 $2 . $date_formattedcp $1 $2 . $date_formatted展開された変数にスペースが含まれていない限り、意図したとおりに機能します。スクリプトを次のように呼び出した場合:
datecp "my old name" "my new name"datecp "my old name" "my new name"展開すると次のコマンドが生成されます。
cp my new name my old name.the_datecp my new name my old name.the_date実際には引数が 6 つあります。
この問題に適切に対処するには、スクリプトの最後の行を次のようにする必要があります。
cp " $1 " " $2 . $date_formatted "cp " $1 " " $2 . $date_formatted "
ご覧のとおり、スクリプトの行を次のように変更します。
cp -iv $1 $2.$date_formatted
に:
cp -iv “$1” “$2”.$date_formatted
名前にスペースが含まれるファイルに対してスクリプトを使用すると、この問題が解決されます。また、Samuel は、このサイト (またはインターネット全般) からコードをコピーして貼り付けるときは、適切なダッシュと引用符を「印刷的により適切な」ものに置き換えるように注意してください。また、コードをよりコピー/ペーストしやすいものにするために、さらに努力していきます。 😉
別のコメント投稿者、 は、ファイル拡張子の前に日付が表示されるようにスクリプトを拡張することにしました。だから代わりに
おいしいファイル.mp3.07_14_11-12.34.56
これが得られます:
おいしいファイル.07_14_11-12.34.56.mp3
これにより、ほとんどのユーザーにとってはもう少し便利になります。彼のコードは 、GitHub ページ から入手できます。彼がファイル名を分解するために何を使用しているかを見てみましょう。
date_formatted=$(日付 +%Y-%m-%d_%H.%M%S)
file_extension=$(echo “$1″|awk -F . ‘{print $NF}’)
ファイル名=$(ベース名 $1 .$ファイル拡張子)
cp -iv $1 $ファイル名-$日付形式.$ファイル拡張子
書式を少し変更しましたが、Myles が 1 行目で日付関数を宣言していることがわかります。ただし、2 行目では、ファイル名を出力するためにスクリプトの最初の引数を指定して「echo」コマンドを使用しています。彼は、パイプ コマンドを使用してその出力を取得し、それを次の部分の入力として使用します。パイプの後、Myles は強力なパターン スキャン プログラムである「awk」コマンドを呼び出します。 -F フラグを使用して、次の文字 (スペースの後) が「フィールド区切り文字」を定義するものであることをコマンドに伝えています。この場合、それはピリオドです。
ここで、awk は、「tastyfile.mp3」という名前のファイルが、「tastyfile」と「mp3」の 2 つのフィールドで構成されていることを確認します。最後に彼が使っているのは、
‘{print $NF}’
最後のフィールドを表示します。ファイルに複数のピリオドがある場合、つまり awk に複数のフィールドを表示させると、最後のピリオド (ファイル拡張子) のみが表示されます。
3 行目では、ファイル名の新しい変数を作成し、「basename」コマンドを使用して、ファイル拡張子を除く $1 内のすべてを参照します。これは、basename を使用し、その引数として $1 を指定し、スペースとファイル拡張子を追加することによって行われます。行 2 を参照する変数により、ファイル拡張子が自動的に追加されます。これにより、次の処理が実行されます。
おいしいファイル.mp3
そしてそれをに変えます
おいしいファイル
次に、最後の行で、Myles はすべてを順番に出力するコマンドをまとめました。スクリプトの 2 番目の引数である $2 への参照がないことに注意してください。この特定のスクリプトは、代わりにそのファイルを現在のディレクトリにコピーします。サミュエルとマイルズ、頑張ったよ!
スクリプトと $PATH の実行
また、「基本」の記事では、デフォルトではスクリプトをコマンドとして参照することは許可されていないことにも言及しています。つまり、スクリプトを実行するには、スクリプトのパスを指定する必要があります。
。/脚本
~/bin/スクリプト
ただし、スクリプトを ~/bin/ に配置すると、どこからでも名前を入力するだけで実行できるようになります。
最新の Linux ディストリビューションではデフォルトでそのディレクトリを作成しないため、コメント投稿者はこれがどれほど適切であるかを時間をかけて議論しました。さらに、デフォルトではこれを $PATH 変数に追加する人もいません。これは、スクリプトをコマンドのように実行するために必要なものです。 $PATH 変数を確認した後、コメント作成者が正しかったため、少し当惑しましたが、それでもスクリプトの呼び出しは機能しました。その理由がわかりました。多くの最新の Linux ディストリビューションは、ユーザーのホーム ディレクトリに特別なファイル (.profile) を作成します。
このファイルは bash によって読み取られます (ユーザーのホーム ディレクトリに .bash_profile が存在しない場合)。その下部には、$PATH 変数が存在する場合は ~/bin/ フォルダーを $PATH 変数に追加するセクションがあります。ということで、その謎は解明されました。このシリーズの残りの部分では、スクリプトを ~/bin/ ディレクトリに配置し続けます。これは、スクリプトはユーザー スクリプトであり、ユーザーが実行できる必要があるためです。そして、実際に動作させるために $PATH 変数を手動でいじる必要はないようです。
ループを使用してコマンドを繰り返す
繰り返しのタスクを処理するためのオタクの武器庫の中で最も便利なツールの 1 つであるループを見てみましょう。今日は「for」ループについて説明します。
for ループの基本的な概要は次のとおりです。
リスト内の変数の場合;する
コマンド1
コマンド2
…
コマンドン
終わり
VARIABLE には任意の変数を指定できますが、慣例により小文字の「i」が使用されることがほとんどです。 LIST は項目のリストです。複数の項目を指定したり (スペースで区切って)、外部テキスト ファイルを指定したり、アスタリスク (*) を使用して現在のディレクトリ内の任意のファイルを指定したりできます。リストされているコマンドは規則に従ってインデントされているため、ネスト、つまりループをループの中に入れることが容易にわかります (つまり、ループ中にループすることができます)。
リストでは区切り文字としてスペースが使用されるため、つまり、スペースはリスト内の次の項目への移動を意味するため、名前にスペースが含まれるファイルはあまりフレンドリーではありません。ここでは、スペースを含まないファイルの操作にこだわりましょう。現在のディレクトリ内のファイルの名前を表示する簡単なスクリプトから始めましょう。 ~/bin/ フォルダーに「loopscript」という名前の新しいスクリプトを作成します。これを行う方法 (実行可能としてマークする方法やハッシュ バン ハックを追加する方法など) を覚えていない場合は 、bash スクリプトの基本に関する記事 を参照してください。
その中に、次のコードを入力します。
item1 item2 item3 item4 item5 item6 の場合。する
「$i」をエコーする
終わり
スクリプトを実行すると、これらのリスト項目が出力として取得されるだけです。
とてもシンプルですよね?状況を少し変更するとどうなるかを見てみましょう。スクリプトを次のように変更します。
* の私にとって;する
「$i」をエコーする
終わり
このスクリプトをフォルダー内で実行すると、スクリプトに含まれるファイルのリストが出力として取得されます。
ここで、echo コマンドをもっと便利なもの、たとえば zip コマンドに変更しましょう。つまり、ファイルをアーカイブに追加します。そして、議論を交えてみましょう。
$@ の私にとって;する
zip アーカイブ「$i」
終わり
何か新しいことがあるよ! 「$@」は「$1 $2 $3 … $n」のショートカットです。言い換えれば、これは指定したすべての引数の完全なリストです。次に、複数の入力ファイルを指定してスクリプトを実行するとどうなるかを見てみましょう。
私のフォルダーにどのファイルがあるかを確認できます。 6 つの引数を指定してコマンドを実行すると、各ファイルが「archive.zip」という名前の zip アーカイブに追加されました。簡単ですよね?
for ループは非常に素晴らしいです。ファイルのリストに対してバッチ関数を実行できるようになりました。たとえば、スクリプトのすべての引数を zip アーカイブにコピーし、元のファイルを別のフォルダーに移動して、その zip ファイルをリモート コンピューターに 自動的に安全にコピー できます。 SSH を使用してキー ファイルを設定すると、パスワードを入力する必要さえなくなり、zip ファイルをアップロードした後にそれを削除するようにスクリプトに指示することもできます。
for ループを使用すると、ディレクトリ内のすべてのファイルに対して一連のアクションを簡単に実行できます。さまざまなコマンドを積み重ねて、引数を使用して非常に簡単にリストを作成し、その場で実行できますが、これは氷山の一角にすぎません。
Bash スクリプタの皆さん、何か提案はありますか?ループを使用する便利なスクリプトを作成しましたか?シリーズについての意見を共有したいですか?コメントを残して、他のスクリプト初心者を助けてください。





