Using ls
is a bit hazardous. See Why *not* parse `ls`?
You will also have to pick apart the filename, otherwise you just append $suffix
to the end of it, as you discovered.
Here follows a solution using find
, and one without find
.
find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +
This will find all regular files in or somewhere under the current directory, whose names does not end with .zip
.
Then the following shell script will be invoked with a list of those files:
suffix="$1" # the suffix is passed as the first command line argument
shift # shift it off $@
for n; do # loop over the remaining names in $@
p=${n%.*} # get the prefix of the file path up to the last dot
s=${n##*.} # get the extension of the file after the last dot
# rename the file if there's not already a file with that same name
[ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done
Testing:
$ touch file{1,2,3}.txt file{a,b,c}.zip
$ ls
file1.txt file2.txt file3.txt filea.zip fileb.zip filec.zip
$ suffix="notZip"
$ find . -type f ! -name '*.zip' -exec sh -c 'suffix="$1"; shift; for n; do p=${n%.*}; s=${n##*.}; [ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"; done' sh "$suffix" {} +
$ ls
file1_notZip.txt file3_notZip.txt fileb.zip
file2_notZip.txt filea.zip filec.zip
The shell script above can be run independently of find
if the number of files are not terribly large and if you don't need to recurse into subdirectories (only slightly modified to skip non-file names):
#!/bin/sh
suffix="$1" # the suffix is passed as the first command line argument
shift # shift it off $@
for n; do # loop over the remaining names in $@
[ ! -f "$n" ] && continue # skip names of things that are not regular files
p=${n%.*} # get the prefix of the file path up to the last dot
s=${n##*.} # get the extension of the file after the last dot
# rename the file if there's not already a file with that same name
[ ! -e "${p}_$suffix.$s" ] && mv "$n" "${p}_$suffix.$s"
done
With bash
, you would run this on the files in a directory like this:
$ shopt -s extglob
$ ./script.sh "notZip" !(*.zip)
With the extglob
shell option set in bash
, !(*.zip)
would match all names in the current directory that does not end with .zip
.
ls
will also print folder names – RomanPerekhrest Oct 05 '17 at 13:35.zip
files will have an extension, primarily.csv
. Not recursive, just in the particular directory. – kstats9pt3 Oct 05 '17 at 14:37