1

For any sequential range of integers, n1..n2how can I use command line tools to parse them into ranges of length <= n?

Example

As a specific example, I have a directory with folders named 1253..2050. Each folder has a script called job.sh, and I can submit them in batches of 20 jobs (since each node has 20 cores). Thus, I want to generate the following commands:

Sample input:

echo {1253..1301}

For a particular case I can generate this sequence of integers using either /bin/ls or cat runs.txt.

Sample output:

qsub -t 1253-1272 array.pbs
qsub -t 1273-1292 array.pbs
qsub -t 1293-1301 array.pbs
David LeBauer
  • 31,011
  • 31
  • 115
  • 189

2 Answers2

2

This should do what you want.

count=20
off=0
dirs=(*)

while (( (off + count) < ${#dirs[@]} )); do
    qsub -t ${dirs[off]}-${dirs[off+count]} array.pbs
    ((off+=count + 1))
done
if [ $off -ne ${#dirs[@]} ]; then
    qsub -t ${dirs[off]}-${dirs[@]: -1} array.pbs
fi

That last if is probably not necessary in your case and this loop sort-of assumes that the ranges are going to be complete (I'm assuming qsub expects that too).

David LeBauer
  • 31,011
  • 31
  • 115
  • 189
Etan Reisner
  • 77,877
  • 8
  • 106
  • 148
  • I am not sure if the condition is being met .. if I replace the qsub line with `echo TRUE`, I don't see any output. Am I missing something? Here is the command I expect to write "TRUE" a bunch of times: `while (( (off + count) < ${#dirs[@]} )); do echo TRUE; ((off+=count + 1)); done` – David LeBauer Jul 13 '15 at 16:45
  • Did you populate the `dirs` array with the directory names? – Etan Reisner Jul 13 '15 at 16:46
  • I set `dirs={1253..1301}` – David LeBauer Jul 13 '15 at 16:50
  • That's not an array that's a string. (It also doesn't expand the string. See `echo "$dirs"`.) Try: `dirs=({1253..1301})` – Etan Reisner Jul 13 '15 at 16:51
  • That's still a string and not an array. The snippet wants an array. `dirs=({1253..1301})` should create an array of those numbers. – Etan Reisner Jul 13 '15 at 17:04
  • I did. See my comment above. If I do `dirs=({1253..1301})`, `echo $dirs` only gives a single number, `1253` – David LeBauer Jul 13 '15 at 17:08
  • Because `$dirs` for an array is the same as `${dirs[0]}` (i.e. the first element). Try `echo "${dirs[@]}"` or `declare -p dirs`. And I missed the first comment in that pair because of scrolling, sorry. – Etan Reisner Jul 13 '15 at 17:09
  • Thats it. Its only missing the final command when there are < 20 left `qsub -t 1295-1301 /job.sh`. But its got 90% of what I need. Thanks – David LeBauer Jul 13 '15 at 17:13
  • That last `if` doesn't cover that case? It does here with `dirs=({1253..1301})` http://ideone.com/P99Ixw – Etan Reisner Jul 13 '15 at 17:18
0

try with this solution, may be can help you:

echo {1253..1301} | tr ' ' "\n" | awk '{print "gksub -t " $1 "/job.sh"}'
David LeBauer
  • 31,011
  • 31
  • 115
  • 189
ggerman
  • 21
  • 5