同じ名前の複数のファイルを追加できるUnixスクリプトを探しています。
たとえば、サーバーには次のファイルがあります。
output2019_1.txt
output2019_2.txt
output2019_3.txt
output2020_1.txt
echo "Hello" | mailx -a "test attachments" -a output2019* [email protected]
上記のスクリプトは2019年のファイルのみを追加します。 2019年3つのファイルをすべて電子メールに添付したいと思います。
電子メール本文の過去のuuencodeではなく、実際の添付ファイルを探しています。
答え1
次の方法で支柱拡張を使用できます。
echo "Hello" | mailx -a "test attachments" '-aoutput2019_'{1..3}.txt [email protected]
答え2
あなたは使用することができprintf
ますコマンドの置き換え:
echo Hello | mailx $(printf -- '-A %s ' output2019*) [email protected]
--
もはやオプション引数がないことをprintfに知らせます(それ以外の場合は-A
無効なオプションについて文句を言います)。残りの各引数(一致するファイル)が印刷されるフォーマット'-A %s '
文字列。output2019*.txt
たとえば、mailx は次のように実行されます。
mailx -A output2019_1.txt -A output2019_2.txt -A output2019_3.txt [email protected]
注:これはすべてのファイル名に対しては機能しません。スペースまたはシェルメタ文字を含むファイル名は失敗します。この問題を解決するには、書式文字列に引用符を含めるだけです。例えば
echo Hello | mailx $(printf -- "-A '%s' " output2019*) [email protected]
これはすべての文字を含むファイル名に適用されます。とは別にアポストロフィ。
以下を含むプロセスファイル名どの文字を有効にするには、まず-Aオプションとファイル名のペアを含む配列を作成する必要があります。例えばプロセスの交換存在するbash
:
mapfile -d '' -t attachments < \
<(find . -maxdepth 1 -name 'output2019*' -printf '-A\0%p\0')
echo Hello | mailx "${attachments[@]}" [email protected]
Bashがこのような配列を拡張すると(つまり、インデックスで二重引用符で囲む[@]
)、配列の各要素は別々の「単語」として扱われます。、追加噴射や解析の影響を受けません。
これにはオプションfind
としてGNU(Linuxの標準)が必要です。ここでは、各ファイル名にNULを出力するように-printf
指示し、ファイル名の後に別のNULが続きます。find
-A
このmapfile
コマンドはstdinから配列を埋め、NULが区切り記号(with)であることを示します...そしてstdinは-d ''
プロセス置換()を介してリダイレクトされます<
。バッシュをfind ...
参照してくださいhelp mapfile
。ところで、readarray
bashの同義語です。mapfile
例のファイル名を使用すると、$attachments
配列は6つの要素で埋められます。
$ declare -p attachments
declare -a attachments=([0]="-A" [1]="./output2019_1.txt" [2]="-A" [3]="./output2019_3.txt" [4]="-A" [5]="./output2019_2.txt")
IMO、これはすべてのファイル名で動作するので、最高のバージョンです。タイピングは少し難しいですが、それほど価値があります。いつも「何が間違っている可能性がありますか?「この点を念頭に置いて、そのようなことが起こらないようにしてください。