findでn番目の結果を取得する方法は?

findでn番目の結果を取得する方法は?

1私は、各並列ジョブにからの整数ID(以下の例でn私が知っている値)を提供するジョブスケジューラを持つ分散コンピューティング/サーバーファームにアクセスできます。nn = 10

私はfind -maxdepth 1 -name '2019 - *'プログラムに引数として渡すファイル名のリストを見つけるのに使います。

サンプルファイル名:

2019 - Alphabet
2019 - Foo Bar
2019 - Reddit
2019 - StackExchange

順序は重要ではありません。一致するすべてのファイルは一度だけ使用できます。

以下は、使用できる「テンプレート」スクリプトの例です。

#!/bin/bash

# in this case, from i = 1 to i = 10
#SBATCH --array=1-10

# pseudocode begins
    # it is given that filename_array has 10 unique elements
    filename_array="$(find -maxdepth 1 -name '2019 - *')"

    # SLURM_ARRAY_TASK_ID is the value of i, from i = 1 to i = 10
    filename=filename_array[$SLURM_ARRAY_TASK_ID]
# pseudocode ends

./a.out "$filename"

これが行うことです(ただし、各プロセスは別のシステムで並列に実行されます)。

./a.out "./2019 - Alphabet" &
./a.out "./2019 - Foo Bar" &
./a.out "./2019 - Reddit" &
./a.out "./2019 - StackExchange" &

与えられた各ファイル名に対してテンプレートスクリプトを一度に実行するbashスクリプトをどのように作成できますかfind -maxdepth 1 -name '2019 - *'

答え1

find特に、現在のディレクトリ内のファイルにのみ興味がある場合は、を使用するのが間違いかもしれません。シェルグローブモードを使用できます。

#/bin/sh

for f in '2019 - '*
do
    [ -f "$f" ] && ./a.out "$f" &
done

ファイルでテストすることは移植性のためです。を使用している場合は、一致しないパターンをそれ自体の代わりになしに拡張して、一致するファイルがない場合は、ループが1回ではなく0回実行されるようにすることができますbashshopt -s nullglobただし、移植性が高く、ディレクトリ名がパターンと一致するなどの状況を処理できます。

明らかに必要なのは「テンプレートスクリプト」ですが、それが意味するものは限定的に理解しています。

おそらく

#!/bin/bash
# magic string for slurm to run on 10 hosts
#SBATCH --array=1-10

filename_array=( '2019 - '* )
filename=${filename_array[$SLURM_ARRAY_TASK_ID-1]}
./a.out "$filename"

それは何ですか?

編集:別の要件が変更されました。パターンの正規表現をサポートします。

#!/bin/bash
# magic string for slurm to run on 10 hosts
#SBATCH --array=1-10

readarray -d '' filename_array < <( find . -maxdepth 1 -regex '.*2019 -.*' -print0 | sort -z )
filename=${filename_array[$SLURM_ARRAY_TASK_ID-1]}
./a.out "$filename"

答え2

あなたはそれを使用できますか$SLURM_JOB_NODELIST

この場合、GNU Parallelは確実な解決策のように見えます。

find -maxdepth 1 -name '2019 - *' |
  parallel --slf $SLURM_JOB_NODELIST --wd . ./a.out {}

関連情報