Want to make txt files for every png in the folder
You can remove the existing extension using the shell's parameter expansion features
${parameter%pattern}
The 'pattern' is matched against the end of 'parameter'. The result is the expanded value of 'parameter' with the shortest match deleted.
So in your case, replace $filePng.txt
with "${filePng%.png}.txt"
You can use the basename
command here:
touch "$folder/$(basename "$filePng" .png).txt"
Note the additional $folder/
. This is neccessary since the basename command removes the path from.
With variation on what steeldriver already mentioned - parameter expansion - we can use string replacement to do the job. Additionally, you should quote variables. Below is your edited script.
#!/bin/bash
folder='/home/data/mnist/training'
for filePng in "$folder"/*
do
touch "${filePng/.png/.txt}"
done
If you have a lot of files to create it would be worthwhile to “touch” more than one file at a time, so that you don't need to fork a new process for each of them (which takes quite some time if performed multiple thousand times).
Option 1: pattern substitution + xargs
This option will supply multiple paths to the touch
command at once, usually a few thousand or whatever the system can fit on a single command line.
find "$folder" -mindepth 1 -maxdepth 1 -name '*.png' -print0 |
sed -ze 's/\.png$/.txt/' |
xargs -r0 -- touch --
Option 2: parameter expansion + command output redirection
This option doesn't run touch
at all but uses Bash/Bourne/POSIX shell features instead which don't require sub-processes at all.
for f in "$folder"/*.png; do
: >> "${f%.png}.txt"
done
If you're confident that you don't have files with .png
somewhere in the middle of the name, then you can just use an array with parameter expansion:
pngs=( /path/to/pngs/*.png )
touch "${pngs[@]/.png/.txt}"
This stores all the paths to the files ending in .png
in an array and then uses parameter expansion to create the list of .txt
files, by substituting .png
for .txt
on each one.
Bear in mind that this will break if you have so many files that they cannot all be passed as arguments to the same invocation of touch
.