0

In a directory, for each file listed by ls -1 . in the default order which is the lexicographic order, I want to do the following

  1. find the next n files starting from and including the file, putting them into an array named train, and copy them into a subdirectory tmp.

  2. find the n+1-th file, putting it into a variable named test

  3. perform some operation on train, test, and tmp. Remove files in tmp.

train and test are reused, and supposed to be overwritten for each file listed by ls.

tmp is supposed to be empty right before starting the above steps for each file listed by ls.

The three steps are performed on each file except the last n files listed by ls, because there is no n+1-th file starting from each of them.

I wonder how to implement the above in bash? Thanks.

For example,

suppose n is 2, and the files listed by ls in the current directory are:

a
b
c
d
e
f

for a, I will find a and b and put them into array train and copy them into dir tmp, and find c and put it in variable test. Then perform some operation on train, test and tmp. Finally, empty dir tmp.

for b, I will find b and c, and put them into array train by overwriting it, and copy them into dir tmp, and find d and put it in variable test by overwriting it. Then perform some operation on train, test and tmp. Finally, empty dir tmp.

Then the above is performed on c and d, but not on e and f, because n=2.

  • If your files name don't contain newline, then ls | tail -n +3 | head -n2 gave you the 3rd and 4th files. – cuonglm Jan 7 '16 at 2:06
  • 1
    Don't parse ls, that's a dirty habit – Sobrique Jan 7 '16 at 14:04
1
#!/bin/bash

declare -a all
all=(`ls -1 | grep -v '^tmp$'`)
n=2
i=0

while [ $((n+i)) -lt ${#all[*]} ]; do
    declare -a train
    j=0
    while [ $j -lt $n ]; do
            train[$j]=${all[$((i+j))]}
            cp ${all[$((i+j))]} tmp/
            j=$((j+1))
    done
    test=${all[$((i+j))]}
    i=$((i+1))
    # do something:
    echo "loop $i: contents of tmp/ are" $(ls tmp)", test=$test"
    rm -f tmp/*
done

First put all the files in the array all.

Now loop while there's space in the array (offset i plus number n is less than the length of the list of files).

Use a loop to put n filenames into array train starting from offset i, and copy the file into subdirectory tmp. After the loop the next filename is put into test.

Now "do something".

Increment the offset i and loop again.

I personally would use perl for this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.