Using standard find
, sh
, and mv
:
find . -type f -name '*.no_sub' -exec sh -c '
for pathname do
mv -- "$pathname" "${pathname%.no_sub}"
done' sh {} +
This finds any regular file with a name that ends in the string .no_sub
, in or below the current directory. For batches of these pathnames, a short in-line shell script is called. This sh -c
script iterates over the given batch of pathnames and renames each of them by removing the .no_sub
filename suffix. The removal of the filename suffix is done using the standard ${variable%suffix}
parameter expansion.
No check is made for filename collisions.
This is similar to the solution provided by Marcus Müller in that the renaming of an individual file happens in an identical way, but uses find
to generate the list of pathnames for the loop in a way that will pick up hidden names and includes an explicit file type filter to iterate over regular files only.
See also: Understanding the -exec option of `find`
Since we know that each filename given to the inline script ends with .no_sub
, we may avoid repeating .no_sub
in there if we want to:
find . -type f -name '*.no_sub' -exec sh -c '
for pathname do
mv -- "$pathname" "${pathname%.*}"
done' sh {} +