次のように、bash でアスタリスクを使用して、ワイルドカードを使用して特定の形式の名前を持つファイルを抽出できることはわかっています。
$ ls
a01 a02 a03 a04 a05 a06 a07 a08 a09 b01 b02 b03 b04 b05 b06 b07 b08 b09
$ ls a*
a01 a02 a03 a04 a05 a06 a07 a08 a09
$ ls b*
b01 b02 b03 b04 b05 b06 b07 b08 b09
a
しかし、a で始まるすべてのファイルを というディレクトリに移動し、b で始まるすべてのファイルを というディレクトリに移動したい場合は b
、それを 1 つのコマンドで実行するにはどうすればよいですか?
次のようなことができますか:
$ mv *0* */
しかし、move-to 引数の最初のアスタリスクを何らかの方法で参照するのでしょうか?
答え1
1 つのコマンド、1 行:
for n in *;do [ -f "$n" ] && case "$n" in a*) mv "$n" a/;; b*) mv "$n" b/;; esac; done
あるいは、ファイル名からディレクトリ名を導き出すこともできますが、行が長くなると予想したため、最初はそれを示しませんでした。たとえば、ループ内のステートメントは次のようになります (最初の試行)。
d=$(echo "$n" | sed -e 's/^\(.\).*/\1/'); [ -f "$n" ] && mv "$n" $d/
は、与えられたファイル名の最初の文字を使ってディレクトリ名を取得します。
[ -f "$n" ] && case "$n" in a*) mv "$n" a/;; *b) mv "$n" b/;; esac
ケース文の場合。実際にはそれほど長くはありませんが、オンザフライで入力するのが難しくなります。bash
前述のように、サブストリング構文を使用して${parameter:offset:length}
その行を短くすることができます。
d=${n:0:1}; [ -f "$n" ] && mv "$n" $d/
または
[ -f "$n" ] && mv "$n" ${n:0:1}/
(これはbashの拡張機能として記憶していますが、POSIX)。
ワイルドカードの再利用に関する実際の質問については、それは明らかにブレース拡張これらは、必要なポイントの前に展開されます。ドキュメントを引用します:
ブレース拡張が行われる前に他の拡張や、他の拡張に特有の文字は結果に保持されます。厳密にテキスト. Bashはない展開のコンテキストまたは中括弧内のテキストに構文解釈を適用します。パラメータ展開との競合を避けるため、文字列 '${' は中括弧展開の対象とは見なされません。