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