Bash 分割ファイル一覧

Bash 分割ファイル一覧

test_1_cfg.dat私のフォルダには、、、test_2_cfg.dat....などの200個のファイルがあります。最初の40個のファイルを入力として含め、いくつかのプロセスを実行するbashスクリプトと、次の40個のファイルを読み込んで別のプロセスを実行する別のスクリプトが必要です。

そのため、ファイル名のリストを取得してからリストを分割する方法を考えていますが、bashでこれを行う方法がわかりません。

どんなアイデアがありますか?

答え1

方法#1 - 頭と尾の使用

このコマンドを使用すると、headファイルリストから最初の40個のファイルを次のように抽出できます。

$ head -40 input_files | xargs ...

次の40を得るには:

$ tail -n +41 input_file  | head -40 | xargs ...

...

$ tail -n +161 input_file | head -40 | xargs ...

同じ技術を使用して、一度に40個ずつリストに従うことができます。

方法2 - xargsの使用

1つの変数にすべてのファイル名がある場合は、xargsそれを使用してリストをX要素の塊に分割できます。

はい

私のファイル名が1-200であるとしましょう。だから、次のような変数にロードします。

$ files=$(seq 200)

この変数の最初のいくつかの項目を見ることができます。

$ echo $files  | head -c 20
1 2 3 4 5 6 7 8 9 10

次に、xargsこれを使用して次のように分割します。

$ xargs -n 40 <<<$files
1 2 3 4 5 6 7 8 9 10 ...
41 42 43 44 45 46 47 ...
81 82 83 84 85 86 87 ...
121 122 123 124 125 ...
141 142 143 144 145 ...
161 162 163 164 165 ...
181 182 183 184 185 ...

その後、上記のコマンドを別のコマンドに渡すと、xargsプログラムが実行されます。

$ xargs -n 40 <<<$files | xargs ...

ファイルリストの内容に変数から簡単にアクセスできない場合は、ファイルを介してxargsリストを提供できます。

$ xargs -n 40 <input_file
1 2 3 4 5 6 7 8 9 10 ...
41 42 43 44 45 46 47 ...
81 82 83 84 85 86 87 ...
121 122 123 124 125 ...
141 142 143 144 145 ...
161 162 163 164 165 ...
181 182 183 184 185 ...

方法 #3 - Bash 配列

ファイル名が Bash 配列にあるとします。今回も、1から200までの一連の数字を使用してファイル名を表します。

$ foo=( $(seq 200) )

次のように配列の内容を表示できます。

$ echo ${foo[@]}
1 2 3 4 5 ....

今、最初の40個を入手してください。

$ echo "${foo[@]:0:40}"

2番目の40など:

$ echo "${foo[@]:40:40}"
...
$ echo "${foo[@]:160:40}"

答え2

完璧なレシピは次のとおりですxargs

cat list_of_files | xargs -n 40 command

引用元man xargs:

 -n number   Set the maximum number of arguments taken from standard input
             for each invocation of the utility.  An invocation of utility
             will use less than number standard input arguments if the
             number of bytes accumulated (see the -s option) exceeds the
             specified size or there are fewer than number arguments
             remaining for the last invocation of utility.  The current
             default value for number is 5000.

各グループに対して異なる操作を実行するには、次の項目に渡す前に関連行をインポートする必要がありますxargs

 sed -n '1,40p' list_of_files | xargs command1
 sed -n '41,80p' list_of_files | xargs command2
 ...     

答え3

ちなみに私は好きですxargs -n 40 <<<$filesが、一行に「40個のパラメータ」があるのでそうしました。

threads=10
xargs -n $((40/threads)) <<<$files

または配列であれば..

n=(1 2 3 4 5 6)
xargs -n $((${#n[@]}/threads))

while read -r input; do
  for item in $input; do
    <..stuff..>
  done &
done <<< $(for x in ${n[@]}; do echo $x; done | xargs -n $((${#n[@]}/threads)))
wait

関連情報