Hi I am looking for a bash solution to batch file renaming. I have files acquired from a digital camera I am importing as time-lapse footage.

Every 1000 images the JPG file renaming jumps as such:


I am trying to hack a reusable shell command that lets me remove the '0' in the 5th position such that the image count is contiguous for importing to After Effects.

Does anybody know the quickest and easiest way to remove the nth character in a set of filenames? I will always have the image set together in a directory with no other files than the image sequence in said directory.

I have searched and solutions so far would seem to remove all '0' characters from the filename which is not what I want; specifically only removing the 5th character is my desired result. Thank you for any time taken to answer this.


Nevermind! Figured out the shell script solution. For those who are here because they have the same problem here is the shell code I used:

cd DIRECTORYPATH         ## Navigate to directory with images

for f in *; do           ## Begin for loop with each file in directory
    x="{f::4}"           ## Set x as first 4 characters
    y="{f:5}"            ## Set y as all characters past position 5
    mv -- "$f" "$x$y"    ## Use mv command to rename each file as string x+y

It's worth citing the relevant man page of the feature you're using. From the EXPANSION section of man bash:

       Substring  Expansion.  Expands to up to length characters of the value of parameter starting at the character specified by offset.  If parameter is @, an 
       indexed array subscripted by @ or *, or an associative array name, the results differ as described below.  If length is omitted, expands to the substring
       of  the value of parameter starting at the character specified by offset and extending to the end of the value.  length and offset are arithmetic expres‐
       sions (see ARITHMETIC EVALUATION below).

       If offset evaluates to a number less than zero, the value is used as an offset in characters from the end of the value of parameter.  If length evaluates
       to  a  number less than zero, it is interpreted as an offset in characters from the end of the value of parameter rather than a number of characters, and
       the expansion is the characters between offset and that result.  Note that a negative offset must be separated from the colon by at least  one  space  to 
       avoid being confused with the :- expansion.

Note that you can perform arithmetic inside ${}, so you could parameterize your code like this:


for f in *JPG; do
   mv -- "$f" "${f:0:$position-1}${f:$position}"


This is a quick-and-dirty solution which doesn't check for the length of filenames or anything, but for a hack like this it should be ok.


Another way is to use sed



for f in *.JPG 
    mv $f $(echo $f | sed -e 's/\(^P[0-9]\{3\}\)0\([0-9]*\.JPG\)/\1\2/')



Use rename (Perl rename or prename).

rename -nv 's/^(.{4})0/$1/' *.jpg

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.