Unix shell script for increment the extension

2019-09-09 21:57发布

问题:

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"

回答1:

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.



回答2:

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}


回答3:

Just another suggestion - in easy to understand code:

#!/bin/bash

file="testfile"
n=1

# Check for existing files with filename and count it
n=$(ls -latr folder/ |grep -i ${file} | wc -l)

# Increment above number
n=$(( $n + 1 ))

# Copy over file with the incremented number
cp $file folder/${file}.${n}