目次:


再訪されたdatecpスクリプト
シェルスクリプトガイドの最初の記事では、ファイル名の末尾に日付を追加した後、ファイルをバックアップディレクトリにコピーするスクリプトを作成しました。
Samuel Dionne-Rielは、変数参照を扱うもっと良い方法があるとコメントで指摘しました。
Arguments are space-separated in the bash shell, it will tokenize when there is a space in the resulted expanded command. In your script,
cp $1 $2.$date_formatted
展開された変数に空白がない限り、意図したとおりに動作します。あなたのスクリプトをこのように呼び出すと:
datecp 'my old name' 'my new name'
展開すると次のコマンドが実行されます。
cp my new name my old name.the_date
実際には6つの議論があります。
この問題に適切に対処するには、スクリプトの最後の行を次のようにする必要があります。
cp '$1' '$2.$date_formatted'
ご覧のとおり、スクリプトの行を以下から変更します:
cp -iv $1 $2.$date_formatted
に:
cp -iv “$1” “$2”.$date_formatted
名前にスペースが含まれているファイルでスクリプトを使用しているときにこの問題を処理します。 Samuelはまた、このサイト(または一般的なインターネット)のコードをコピーして貼り付けるときには、それらを置き換えることが多い「印刷的に優れた」ものを適切なダッシュと引用符に置き換えることを忘れないように注意します。私たちのコードがよりコピー/ペーストに適していることを確認するために、さらに努力していきます。;-)
別のコメント作成者、Myles Braithwaiteは、ファイル拡張子の前に日付が表示されるようにスクリプトを展開することに決めました。だから代わりに
tastyfile.mp3.07_14_11-12.34.56
私たちはこれを得るでしょう:
tastyfile.07_14_11-12.34.56.mp3
ほとんどのユーザーにとってもう少し便利になっています。彼のコードは彼のGitHubページで入手できます。彼がファイル名を分離するために使用するものを見てみましょう。
date_formatted=$(date +%Y-%m-%d_%H.%M%S) file_extension=$(echo “$1″|awk -F. ‘{print $NF}’) file_name=$(basename $1.$file_extension)
cp -iv $1 $file_name-$date_formatted.$file_extension
私はフォーマットを少し変更しましたが、MylesがLine 1で日付機能を宣言していることがわかります。しかし、Line 2では、スクリプトの最初の引数に "echo"コマンドを使用してファイルの名前を出力します。彼はpipeコマンドを使用してその出力を取り出し、次の部分の入力として使用します。パイプの後、Mylesは "awk"コマンドを呼び出します。これは強力なパターンスキャンプログラムです。 -Fフラグを使用して、次の文字(スペースの後)が "フィールド区切り文字"を定義するものであることをコマンドに伝えます。この場合、それは期間です。
さて、awkは "tastyfile.mp3"という名前のファイルを "tastyfile"と "mp3"という2つのフィールドで構成しています。最後に、彼は
‘{print $NF}’
最後のフィールドを表示します。あなたのファイルに複数のピリオドがある場合、awkに複数のフィールドが表示されます。ファイル拡張子である最後のものだけが表示されます。
3行目で、彼はファイル名の新しい変数を作成し、 "basename"コマンドを使って$ 1のすべてを参照します を除いて ファイル拡張子。これは、basenameを使用して$ 1を引数として与え、スペースとファイル拡張子を追加することで行います。ファイル拡張子は、行2を参照する変数のために自動的に追加されます。これは、take
tastyfile.mp3
それを
tastyfile
最後の行で、Mylesはすべてを順番に出力するコマンドをまとめました。スクリプトの2番目の引数$ 2への参照はないことに注意してください。この特定のスクリプトは、そのファイルを現在のディレクトリにコピーします。素晴らしい仕事SamuelとMyles!
スクリプトと$ PATHの実行
基本的な記事では、デフォルトでスクリプトをコマンドとして参照することはできません。つまり、スクリプトを実行するには、スクリプトのパスを指す必要があります。
./script
~/bin/script
しかし、あなたのスクリプトを〜/ bin /に置くことによって、どこからでもそれらの名前を入力して実行させることができます。
コメント者は、現代のLinuxディストリビューションがそのディレクトリをデフォルトで作成していないので、これがどれほど適切かを議論するのに少し時間を費やしました。さらに、デフォルトでは$ PATH変数には誰も追加しません。これは、スクリプトをコマンドのように実行するために必要なことです。私は$ PATH変数を調べた後、コメント作成者は正しかったが、スクリプトを呼び出すことはまだ私のために働いていたので、やや戸惑っていた。私はなぜか分かりました:現代のLinuxディストリビューションの多くは、ユーザのホームディレクトリにある特別なファイル(.profile)を作成しています。
このファイルはbashによって読み込まれます(.bash_profileがユーザーのホームディレクトリに存在しない場合)。また、$ PATH変数が存在する場合は〜/ bin /フォルダーを追加するセクションがあります。それで、その謎は解消されます。残りのシリーズでは、スクリプトは〜/ bin /ディレクトリに置いていきます。スクリプトはユーザスクリプトであり、ユーザが実行できるはずです。そして、実際には$ PATH変数を手作業で動かす必要はありません。
ループによるコマンドの繰り返し
反復的なタスクを処理するためのオタクの最も有用なツールの1つに到達しましょう:ループ。今日、 "for"ループについて議論します。
forループの基本的な概要は次のとおりです。
for VARIABLE in LIST; do command1 command2 … commandn done
VARIABLEには任意の変数を使用できますが、ほとんどの場合小文字の "i"は慣例によって使用されます。 LISTはアイテムのリストです。複数の項目を指定するか(空白で区切る)、外部テキストファイルをポイントするか、アスタリスク(*)を使用してカレントディレクトリ内のファイルを指定することができます。リストされているコマンドは慣例により字下げされているので、ネスティング - ループ内にループを置くのが簡単です(ループ中にループできるように)。
リストは区切り文字としてスペースを使用するため、スペースはリスト内の次の項目に移動することを意味します。名前にスペースを含むファイルはそれほど親切ではありません。今のところ、スペースなしのファイルで作業してみましょう。まず、現在のディレクトリにあるファイルの名前を表示する簡単なスクリプトから始めましょう。 〜/ bin /フォルダに "loopscript"という名前の新しいスクリプトを作成します。実行方法としてマークし、ハッシュ・バング・ハックを追加する方法を覚えていない場合は、bashスクリプトの基礎資料を参照してください。
その中に次のコードを入力します:
for i in item1 item2 item3 item4 item5 item6; do echo “$i” done
スクリプトを実行するときには、それらのリスト項目を出力として取得するだけです。
かなり簡単ですね。少し変更したらどうなるか見てみましょう。スクリプトに以下のように変更します:
for i in *; do echo “$i” done
このスクリプトをフォルダ内で実行すると、そのスクリプトが出力として含むファイルのリストを取得する必要があります。
echoコマンドをもっと便利なもの、例えばzipコマンドに変更しましょう。つまり、ファイルをアーカイブに追加します。そして、ミックスでいくつかの議論をしましょう!
for i in [email protected]; do zip archive “$i” done
新しいものがあります! "$ @"は "$ 1 $ 2 $ 3 … $ n"のショートカットです。つまり、指定したすべての引数の完全なリストです。さて、いくつかの入力ファイルでスクリプトを実行するとどうなるか見てみましょう。
自分のフォルダにあるファイルを確認できます。私は6つの引数でコマンドを実行し、各ファイルは "archive.zip"という名前の圧縮されたアーカイブに追加されました。簡単だよね?
forループはかなり素晴らしいです。これで、ファイルのリストに対してバッチ関数を実行できるようになりました。たとえば、すべてのスクリプトの引数をZIP形式のアーカイブにコピーし、元のファイルを別のフォルダに移動し、そのzipファイルをリモートコンピュータに自動的にコピーすることができます。 SSHでキーファイルを設定すると、パスワードを入力する必要がなくなり、アップロード後にzipファイルを削除するようスクリプトに指示することもできます。
for-loopsを使うと、ディレクトリ内のすべてのファイルに対して一連のアクションを簡単に実行できます。あなたは多種多様なコマンドを一緒に積み重ねることができ、引数を非常に簡単に使用してオンザフライリストを作成することができます。これは氷山の一角に過ぎません。
Bashスクリプター、あなたは何か提案がありますか?ループを使用する便利なスクリプトを作成しましたか?あなたのシリーズの考えを共有したいですか?いくつかのコメントを残し、他のスクリプト初心者を助けてください!