不特定数の入力値を繰り返して、各入力値に対して同じことを行うスクリプトを作成しようとしています。次のファイル~/bin/trash
:
#!/usr/bin/env bash
for f in "$@"
do
mv f ~/trashcan
done
私はこのように使います。
$touch 2.txt 3.txt 4.txt # create demo files
$trash *.txt
前述のように、Git Bash(Windows)でこのプログラムを実行すると、次のエラーが発生します。
bash: syntax error near unexpected token `2.txt'
答え1
努力する:
#!/usr/bin/env bash
for f; do
mv "$f" ~/trashcan
done
- 'マーキングは
$
必須です呼ぶ宣言された変数($f
) for f in "$@"
ここでは必要ありません
答え2
コードでループ本文を忘れました$
。スペースなどのファイル名をサポートするf
には、この内容を正しく引用する必要があります。"$f"
しかし、これがエラーメッセージの原因であるかどうかはわかりません(そしてそのエラーを引き起こすコードは何も表示されません)。私が予想したエラーは、No such file or directory
存在しない項目を移動したいということでしたf
。
このような小さなユーティリティの場合は、ファイルのシェル関数に変換できます~/.bashrc
。
trash () {
local trashcan="$HOME/trashcan"
mkdir -p "$trashcan"
mv -f -v "$@" "$trashcan"
}
この機能は、コンテンツをごみ箱フォルダに移動する前に実際に存在することを確認します。また、移動する項目の名前を表示しながら、詳細に移動を行います。
"$@"
コマンドラインから関数で指定された名前に正しく拡張されるため、ここで繰り返す必要はありません。
実際の反復名を求める唯一の理由は、移動を実行する前にターゲットが存在しないことを確認したい場合ですmv
(新しいアイテムがごみ箱の内容を上書きしないように)。 GNU coreutilsを使用すると、mv
次の方法で自動化できます。
mv -f -v --backup=numbered "$@" "$trashcan"
GNUでない場合は、mv
次のループが必要になることがあります(このループはmv
上記のシェル関数のループを置き換えます)。
local trash_ext="$RANDOM"
for name; do
while [ -e "$trashcan/${name##*/}.$trash_ext" ]; do
trash_ext="$RANDOM"
done
mv -f -v "$name" "$trashcan/${name##*/}.$trash_ext"
done
これは、ファイル名の後にランダムな数字を追加して一意の名前を作成するための迅速で汚い方法です。その${name##*/}
エントリはデフォルト名(パス名のファイル名部分)に拡張され$name
ます$( basename "$name" )
。