0

I have file getting generated (testfile) eachtime a script is run in working directory. I have to copy that generated file to a directory (testfolder) and have it incremented by a .ext

If the script is run for first time then copy the testfile to testfolder as "testfile.0" and when run second time copy the testfile to testfolder as "testfile.1" and so on.

My script:

#!/bin/sh

file="testfile"
n=1

ls folder/${file}* | while read i
do
  if [ folder/${file}.${n} = ${i} ]
  then
   n=$(( $n + 1 ))
 fi
 done

 cp testfile folder/${file}.${n}

this is only working for first increment "folder/testfile.0"

2 Answers 2

2

I won't correct your solution, since mklement0 does it well.

Here is another solution, without any loop:

file="testfile"
n_max=$(ls -1 "folder/${file}"* | egrep -o '[0-9]+$' | sort -rn | head -n 1)
cp "${file}" "folder/${file}.$((n_max+1))"

Here is the thing of the second line: first you list the files, then egrep extracts the digit extension, then sort -rg sorts them decreasingly, and last head catchs only the first line, i.e. the largest used index. Finally, in the third line, you add one to this max to build your new index. It is ok on my script if the list is empty.

By the way, listing a directory may be quite long, so I suggest you to store somewhere the last index you used for later use. Save it as a variable in the script, or even in a file ... it can save you also some time.

Sign up to request clarification or add additional context in comments.

4 Comments

Nicely done; could you please remove the spaces around the = on the 2nd line? They break the command. A quibble: the $[] syntax for arithmetic expressions is apparently deprecated (see wiki.bash-hackers.org/syntax/expansion/arith); thus, $((n_max+1)) is the safer choice Also: if you're dealing with string representations of integers when sorting, -n (--numeric-sort) is apparently preferable to -g (--general-numeric-sort) - see stackoverflow.com/a/1255800/45375
@mkelement0: Thank you very much for your valuable comments, changes are done.
My pleasure. Your solution is a great alternative to the OP's approach; it prompted me to research the $[] construct (which I'd never seen before) and (finally, after always wondering) the difference between sort's -n and -g options.
@mkelement0: In return, you pointed out the new syntax $((...)), so I've learned quite much about this topic thanks to you!
1

The problem is that your while loop is executed in a subshell due to use of a pipe, so your modifications of n do not work as intended.

In general, you could use process substitution with while to avoid this problem, but in the case at hand a simple for loop is the right approach:

#!/bin/sh

file="testfile"
n=1

for i in folder/${file}*
do
  if [ folder/${file}.${n} = ${i} ]
  then
   n=$(( $n + 1 ))
 fi
done

cp testfile folder/${file}.${n}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.