リモートサーバー上のファイルを分類して検索するbashスクリプトがあります。ファイル名に基づく分類ステップに問題があります。
ファイル名の先頭に定義されているさまざまなファイルシリーズを正しく識別できます。
ala-olo_ulu-1602915797.txt
ala-olo_ulu-1602915799.txt
ili-olo-1602915897.txt
ili-olo-1602915997.txt
ili-olo-pip-1602925797.txt
ili-olo-pip-1602935797.txt
この例には3つの家族があります。
ala-olo_ulu
ili-olo
ili-olo-pip
(純粋な例:))
各家族はループの1回の反復として扱われます。これらの反復では、変数で使用できる家族名がありますBASE_NAME
(例ili-olo
:)。
私の問題は、ファイルをローカルにrsync'ingする前に、次のsshコマンドを使用して管理することです。
ssh root@"${RMT_IP}" '
for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do
tar -rf "'${BASE_NAME}'.tar" ${FILE} --remove-files
done' < /dev/null
残念ながら、このスクリプトを使用すると、ili-olo
以前に管理されていた場合、ili-olo-pip
アーカイブに2つのシリーズ(両方とも同じ起動を共有します)が含まれます。管理されると、ili-olo-pip
これ以上ファイルではなく、tarコマンドはエラーで終了します。 (これが私が問題を見つけた方法です)。
私は、ファイル名の変数部分が数値部分であることを指定するために正規表現を使用する必要があると思いました。for
同じ文字列で始まるシリーズが同じtarに入らないように、ループ定義をどのように変更できますか?
for FILE in "'${BASE_NAME}'*'${FILE_EXTENSION}'"; do
?
たとえば、数値部分は常に同じ桁数を持ちます(秒単位のタイムスタンプです)。1602915797
ご協力ありがとうございます。良い一日をお過ごしください、ベスト、ピエール
答え1
ローカルシェルとリモートシェルの両方で利用可能であれば、はるかにzsh
簡単です。
ssh root@$RMT_IP zsh << EOF
set -o extendedglob # for (#c10)
for file in ${(qq)BASE_NAME}-[0-9](#c10).${(qq)FILE_EXTENSION}(N); do
tar -rf ${(qq)BASE_NAME}.tar \$file --remove-files
done
EOF
[0-9](#c10)
10進数シーケンスと一致します。[0-9]##
1つ以上の数字、または(必ずしもそうではありません)、同じ10進数のシーケンスで構成される範囲の数字を参照してください。[0-9](#c1,)
<100000-9999999999>
extendedglob
sshd
サーバーでユーザーのログインシェルを実行して、引数として渡されたコードを解釈します。私たちはそれが何であるかわからないので(通常root
)シェルを起動し、標準入力にコードを渡すためにsh
このコードを作成します。zsh
zsh
zsh
このようなドキュメントを使用すると、リモートシェルで解釈されるシェルコードをより簡単に構成できます。引用されていないため、EOF
ローカルシェルはローカルで拡張を実行します。
ローカルで実行する必要がある拡張機能とリモートシェルで実行する必要がある拡張子を追跡することが重要です。
上記は${(qq)BASE_NAME}
ローカルシェルによって拡張されます。(qq)
パラメータ拡張フラグを使用して結果を一重引用符で囲み、リモートシェルがそれをリテラル文字列として扱うようにします。
$file
リモートシェルで拡張する必要があるため、リテラルをリモートシェルに渡す\
ためにプレフィックスを付けます。$file
zsh
リモートコンピュータで利用できないが利用可能な場合は、bash
次のことができます(まだzsh
ローカルで作業しています)。
ssh root@$RMT_IP bash --norc << EOF
shopt -s extglob nullglob # for +(...)
export LC_ALL=C
for file in ${(qq)BASE_NAME}-+([0-9]).${(qq)FILE_EXTENSION}; do
tar -rf ${(qq)BASE_NAME}.tar "\$file" --remove-files
done
EOF
bash
zsh
glob演算子と同等のものはありませんが、x(#c10)
使用されると、1つ以上の一致を含むkshのサブセット(残念ながらここにはありません)extglob
をサポートします。これは10以外の1つ以上の数字と一致します。{10}(x)
+(x)
x
+([0-9])
10桁の数字を一致させるには、これを実行できます[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]
。