I have a list of folders. Each folder names for example:
- pippo1 containing the file pippo1.txt,
- pippo2 containing the file pippo2.txt,
- pippo3 containing the file pippo3.txt etc.
I would like to go in the first folder, remove the number from the filename pippo1.txt and then exit, go in the second folder called pippo2 containing the file pippo2.txt, remove 2 from the file name etc etc. I tried the following code, but it doesn’t work! the code is:
for i in *
do
cd $i
ls *.txt | sed -e "s/[0-9]//g"
cd ..
done
What am I doing wrong?
If the requirements are just that simple, then you can do this with only bash substitution:
However, this will fail on more than single digits in the filename, e.g.
pippo999/pippo999.txt. This can be addressed by setting theextgloboption:The
+(...)construct in bash file globbing is only available whenextglobis set.Instead of traversing the directory tree with a loop and
cd, this usesfindto get a list of all the relevant files, then loops over that list of filenames, which will be of the form:./pippoN/pippoN.txt. The rename uses bash parameter replacement to get the modified file name. See also filename expansion.Note that spaces in file or directory names will break this approach, beginning with the use of
find: a path that includes spaces will be split up into multiple tokens around the spaces with each token being a separate result in the list iterator. So if you need to anticipate space characters in the paths then this becomes a bit more complicated:Here we’ve quoted the filenames for the
mvcommand, which will handle spaces correctly, and we’ve changed the field separatorIFSso that bash won’t recognize whitespace as a word boundary. This will fix up the problem withfindin the loop iterator. Now spaces in the path will be handled correctly, so that e.g../pippo 9/pippo9.txtwill also be renamed to:./pippo 9/pippo.txt.