I need to add the word \"hallo\" at the end of each filename before extension in the given directory. but my code produces no output. the echo statements give no output and the
With bash this can be done simplier like:
for f in *;do
echo "$f" "${f%.*}hallo.${f##*.}"
done
example:
$ ls -all
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file1.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file2.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file3.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file4.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file5.txt
$ for f in *;do mv -v "$f" "${f%.*}hallo.${f##*.}";done
'file1.txt' -> 'file1hallo.txt'
'file2.txt' -> 'file2hallo.txt'
'file3.txt' -> 'file3hallo.txt'
$ ls -all
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file1hallo.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file2hallo.txt
-rw-r--r-- 1 29847 29847 0 Aug 21 14:33 file3hallo.txt
This works because ${f%.*}
returns filename without extension - deletes everything (*) from the end (backwards) up to first/shortest found dot.
On the other hand this one ${f##*.}
deletes everything from the beginning up to the longest found dot, returning only the extension.
To overcome the extensionless files problem as pointed out in comments you can do something like this:
$ for f in *;do [[ "${f%.*}" != "${f}" ]] && echo "$f" "${f%.*}hallo.${f##*.}" || echo "$f" "${f%.*}hallo"; done
file1.txt file1hallo.txt
file2.txt file2hallo.txt
file3.txt file3hallo.txt
file4 file4hallo
file5 file5hallo
If the file has not an extension then this will yeld true "${f%.*}" == "${f}"