Bash misinterpreting a sed statement to rename files [duplicate]











up vote
3
down vote

favorite
2













This question already has an answer here:




  • Can't use exclamation mark (!) in bash?

    7 answers




I would like to rename a series of files named this way



name (10).ext
name (11).ext
...


to



name_10.ext
name_11.ext
...


This one-liner works:



$ for i in name (* ; do echo "$i" | sed -e 's! (([0-9]{2}))!_1!' ; done
name_10.ext
name_11.ext
...


But this one doesn't:



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's! (([0-9]{2}))!_1!')" ; done
bash: !_1!': event not found


Why? How to avoid this?





Using



$ bash --version
GNU bash, versione 4.3.48(1)-release (x86_64-pc-linux-gnu)


on Ubuntu 18.04.





While in this similar question a simple case with ! is shown, here a ! just inside single quotes is considered and compared to a ! inside single quotes, inside double quotes. As pointed out in the comments, Bash behaves in a different way in these two cases. This is about Bash version 4.3.48(1); this problem seems instead to be no more present in 4.4.12(1) (it is however recommended to avoid this one-liner, because the Bash version may be unknown in some cases).



As suggested in the Kusalananda answer, if the sed delimiter ! is replaced with #,



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's# (([0-9]{2}))#_1#')" ; done


this problem does not arise at all.










share|improve this question















marked as duplicate by elbarna, schily, don_crissti, Thomas, mosvy Nov 22 at 20:03


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:11






  • 1




    Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
    – steeldriver
    Nov 22 at 13:11






  • 1




    @steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
    – ctrl-alt-delor
    Nov 22 at 13:18















up vote
3
down vote

favorite
2













This question already has an answer here:




  • Can't use exclamation mark (!) in bash?

    7 answers




I would like to rename a series of files named this way



name (10).ext
name (11).ext
...


to



name_10.ext
name_11.ext
...


This one-liner works:



$ for i in name (* ; do echo "$i" | sed -e 's! (([0-9]{2}))!_1!' ; done
name_10.ext
name_11.ext
...


But this one doesn't:



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's! (([0-9]{2}))!_1!')" ; done
bash: !_1!': event not found


Why? How to avoid this?





Using



$ bash --version
GNU bash, versione 4.3.48(1)-release (x86_64-pc-linux-gnu)


on Ubuntu 18.04.





While in this similar question a simple case with ! is shown, here a ! just inside single quotes is considered and compared to a ! inside single quotes, inside double quotes. As pointed out in the comments, Bash behaves in a different way in these two cases. This is about Bash version 4.3.48(1); this problem seems instead to be no more present in 4.4.12(1) (it is however recommended to avoid this one-liner, because the Bash version may be unknown in some cases).



As suggested in the Kusalananda answer, if the sed delimiter ! is replaced with #,



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's# (([0-9]{2}))#_1#')" ; done


this problem does not arise at all.










share|improve this question















marked as duplicate by elbarna, schily, don_crissti, Thomas, mosvy Nov 22 at 20:03


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.















  • Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:11






  • 1




    Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
    – steeldriver
    Nov 22 at 13:11






  • 1




    @steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
    – ctrl-alt-delor
    Nov 22 at 13:18













up vote
3
down vote

favorite
2









up vote
3
down vote

favorite
2






2






This question already has an answer here:




  • Can't use exclamation mark (!) in bash?

    7 answers




I would like to rename a series of files named this way



name (10).ext
name (11).ext
...


to



name_10.ext
name_11.ext
...


This one-liner works:



$ for i in name (* ; do echo "$i" | sed -e 's! (([0-9]{2}))!_1!' ; done
name_10.ext
name_11.ext
...


But this one doesn't:



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's! (([0-9]{2}))!_1!')" ; done
bash: !_1!': event not found


Why? How to avoid this?





Using



$ bash --version
GNU bash, versione 4.3.48(1)-release (x86_64-pc-linux-gnu)


on Ubuntu 18.04.





While in this similar question a simple case with ! is shown, here a ! just inside single quotes is considered and compared to a ! inside single quotes, inside double quotes. As pointed out in the comments, Bash behaves in a different way in these two cases. This is about Bash version 4.3.48(1); this problem seems instead to be no more present in 4.4.12(1) (it is however recommended to avoid this one-liner, because the Bash version may be unknown in some cases).



As suggested in the Kusalananda answer, if the sed delimiter ! is replaced with #,



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's# (([0-9]{2}))#_1#')" ; done


this problem does not arise at all.










share|improve this question
















This question already has an answer here:




  • Can't use exclamation mark (!) in bash?

    7 answers




I would like to rename a series of files named this way



name (10).ext
name (11).ext
...


to



name_10.ext
name_11.ext
...


This one-liner works:



$ for i in name (* ; do echo "$i" | sed -e 's! (([0-9]{2}))!_1!' ; done
name_10.ext
name_11.ext
...


But this one doesn't:



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's! (([0-9]{2}))!_1!')" ; done
bash: !_1!': event not found


Why? How to avoid this?





Using



$ bash --version
GNU bash, versione 4.3.48(1)-release (x86_64-pc-linux-gnu)


on Ubuntu 18.04.





While in this similar question a simple case with ! is shown, here a ! just inside single quotes is considered and compared to a ! inside single quotes, inside double quotes. As pointed out in the comments, Bash behaves in a different way in these two cases. This is about Bash version 4.3.48(1); this problem seems instead to be no more present in 4.4.12(1) (it is however recommended to avoid this one-liner, because the Bash version may be unknown in some cases).



As suggested in the Kusalananda answer, if the sed delimiter ! is replaced with #,



$ for i in name (* ; do mv "$i" "$(echo "$i" | sed -e 's# (([0-9]{2}))#_1#')" ; done


this problem does not arise at all.





This question already has an answer here:




  • Can't use exclamation mark (!) in bash?

    7 answers








bash shell ubuntu sed files






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 15:53

























asked Nov 22 at 12:39









BowPark

1,53482545




1,53482545




marked as duplicate by elbarna, schily, don_crissti, Thomas, mosvy Nov 22 at 20:03


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.






marked as duplicate by elbarna, schily, don_crissti, Thomas, mosvy Nov 22 at 20:03


This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.














  • Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:11






  • 1




    Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
    – steeldriver
    Nov 22 at 13:11






  • 1




    @steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
    – ctrl-alt-delor
    Nov 22 at 13:18


















  • Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:11






  • 1




    Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
    – steeldriver
    Nov 22 at 13:11






  • 1




    @steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
    – ctrl-alt-delor
    Nov 22 at 13:18
















Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
– ctrl-alt-delor
Nov 22 at 13:11




Bounty for any one that can explain why. I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
– ctrl-alt-delor
Nov 22 at 13:11




1




1




Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
– steeldriver
Nov 22 at 13:11




Hmm... there does seem to be a difference in behavior here between bash 4.3.48 and bash 4.4.19 using a simple test echo "$(echo '!foo')". I wonder if 4.3 is erroneously applying the "single quotes lose their special meaning inside double quotes" rule even when the former are within a command substitution?
– steeldriver
Nov 22 at 13:11




1




1




@steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
– ctrl-alt-delor
Nov 22 at 13:18




@steeldriver seems correct. I have not looked at the bug tracker, but version 4.4.12(1) seems to get it correct. Better to avoid for a few years, as there will me plenty of all bash around for a bit. steeldriver write-up in an answer, and send me a reminder, when I can set the bounty in a few days.
– ctrl-alt-delor
Nov 22 at 13:18










3 Answers
3






active

oldest

votes

















up vote
7
down vote



accepted










When used in an interactive shell, the ! may initiate history expansion (not an issue in scripts).



The solution is to use another delimiter than ! in the sed expression.



An alternative bash loop:



for name in "name ("*").ext"; do
if [[ "$name" =~ (.*)" ("([^)]+)").ext" ]]; then
newname="${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.ext"
printf 'Would move %s to %sn' "$name" "$newname"
# mv -i "$name" "$newname"
fi
done





share|improve this answer























  • Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
    – BowPark
    Nov 22 at 13:01










  • I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:09






  • 1




    @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
    – Kusalananda
    Nov 22 at 13:09






  • 1




    @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
    – Kusalananda
    Nov 22 at 13:11










  • Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
    – R..
    Nov 22 at 14:41




















up vote
3
down vote













You can use Larry Wall's rename command (rename package in Debian, prename in RedHat): it uses the (much easier IMHO) Perl regex syntax, and will iterate the file args (no need to code a loop):



rename 's/ (d+)/_$1/' name *





share|improve this answer





















  • Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
    – BowPark
    Nov 22 at 13:03








  • 1




    It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
    – ctrl-alt-delor
    Nov 22 at 13:06










  • Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
    – xenoid
    Nov 22 at 14:41




















up vote
1
down vote













If you know the exact range, you can rename the files like this:



for i in {10..99}; do mv "name ($i).ext" "name_$i.ext"; done


Or, if you want to be POSIX-pedantic:



for i in `seq 10 99`; do mv "name ($i).ext" "name_$i.ext"; done





share|improve this answer




























    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote



    accepted










    When used in an interactive shell, the ! may initiate history expansion (not an issue in scripts).



    The solution is to use another delimiter than ! in the sed expression.



    An alternative bash loop:



    for name in "name ("*").ext"; do
    if [[ "$name" =~ (.*)" ("([^)]+)").ext" ]]; then
    newname="${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.ext"
    printf 'Would move %s to %sn' "$name" "$newname"
    # mv -i "$name" "$newname"
    fi
    done





    share|improve this answer























    • Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
      – BowPark
      Nov 22 at 13:01










    • I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
      – ctrl-alt-delor
      Nov 22 at 13:09






    • 1




      @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
      – Kusalananda
      Nov 22 at 13:09






    • 1




      @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
      – Kusalananda
      Nov 22 at 13:11










    • Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
      – R..
      Nov 22 at 14:41

















    up vote
    7
    down vote



    accepted










    When used in an interactive shell, the ! may initiate history expansion (not an issue in scripts).



    The solution is to use another delimiter than ! in the sed expression.



    An alternative bash loop:



    for name in "name ("*").ext"; do
    if [[ "$name" =~ (.*)" ("([^)]+)").ext" ]]; then
    newname="${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.ext"
    printf 'Would move %s to %sn' "$name" "$newname"
    # mv -i "$name" "$newname"
    fi
    done





    share|improve this answer























    • Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
      – BowPark
      Nov 22 at 13:01










    • I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
      – ctrl-alt-delor
      Nov 22 at 13:09






    • 1




      @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
      – Kusalananda
      Nov 22 at 13:09






    • 1




      @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
      – Kusalananda
      Nov 22 at 13:11










    • Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
      – R..
      Nov 22 at 14:41















    up vote
    7
    down vote



    accepted







    up vote
    7
    down vote



    accepted






    When used in an interactive shell, the ! may initiate history expansion (not an issue in scripts).



    The solution is to use another delimiter than ! in the sed expression.



    An alternative bash loop:



    for name in "name ("*").ext"; do
    if [[ "$name" =~ (.*)" ("([^)]+)").ext" ]]; then
    newname="${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.ext"
    printf 'Would move %s to %sn' "$name" "$newname"
    # mv -i "$name" "$newname"
    fi
    done





    share|improve this answer














    When used in an interactive shell, the ! may initiate history expansion (not an issue in scripts).



    The solution is to use another delimiter than ! in the sed expression.



    An alternative bash loop:



    for name in "name ("*").ext"; do
    if [[ "$name" =~ (.*)" ("([^)]+)").ext" ]]; then
    newname="${BASH_REMATCH[1]}_${BASH_REMATCH[2]}.ext"
    printf 'Would move %s to %sn' "$name" "$newname"
    # mv -i "$name" "$newname"
    fi
    done






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Nov 22 at 13:06

























    answered Nov 22 at 12:43









    Kusalananda

    119k16223364




    119k16223364












    • Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
      – BowPark
      Nov 22 at 13:01










    • I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
      – ctrl-alt-delor
      Nov 22 at 13:09






    • 1




      @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
      – Kusalananda
      Nov 22 at 13:09






    • 1




      @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
      – Kusalananda
      Nov 22 at 13:11










    • Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
      – R..
      Nov 22 at 14:41




















    • Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
      – BowPark
      Nov 22 at 13:01










    • I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
      – ctrl-alt-delor
      Nov 22 at 13:09






    • 1




      @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
      – Kusalananda
      Nov 22 at 13:09






    • 1




      @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
      – Kusalananda
      Nov 22 at 13:11










    • Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
      – R..
      Nov 22 at 14:41


















    Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
    – BowPark
    Nov 22 at 13:01




    Ok! Thanks. But, out of curiosity: why does the first one-liner work, then? It contains ! as well.
    – BowPark
    Nov 22 at 13:01












    I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:09




    I am struggling with this. I have never had a problem, until trying to reproduce this. Some how the outer double quotes disable the inner single quotes, even though the inner quotes are in a sub-shell (). Can you enlighten.
    – ctrl-alt-delor
    Nov 22 at 13:09




    1




    1




    @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
    – Kusalananda
    Nov 22 at 13:09




    @BowPark The parsing of history expansion expressions is a bit of a mystery to me, and it seems to not obey ordinary quoting rules. In the first command, the ! occurs in a single-quoted string. That's the case in the second command as well, but that is included inside a double-quoted string (not taking the fact that there should not be a an issue since the single quoted ! is in a command substitution).
    – Kusalananda
    Nov 22 at 13:09




    1




    1




    @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
    – Kusalananda
    Nov 22 at 13:11




    @ctrl-alt-delor Yeah. History expansions in bash hos always been a bit of a black box to me. It's the quotes. The parsing of the history expansion does not seem to obey normal scoping rules.
    – Kusalananda
    Nov 22 at 13:11












    Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
    – R..
    Nov 22 at 14:41






    Better: set +H to disable this hideous bash misfeature. Add it to your .bashrc.
    – R..
    Nov 22 at 14:41














    up vote
    3
    down vote













    You can use Larry Wall's rename command (rename package in Debian, prename in RedHat): it uses the (much easier IMHO) Perl regex syntax, and will iterate the file args (no need to code a loop):



    rename 's/ (d+)/_$1/' name *





    share|improve this answer





















    • Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
      – BowPark
      Nov 22 at 13:03








    • 1




      It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
      – ctrl-alt-delor
      Nov 22 at 13:06










    • Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
      – xenoid
      Nov 22 at 14:41

















    up vote
    3
    down vote













    You can use Larry Wall's rename command (rename package in Debian, prename in RedHat): it uses the (much easier IMHO) Perl regex syntax, and will iterate the file args (no need to code a loop):



    rename 's/ (d+)/_$1/' name *





    share|improve this answer





















    • Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
      – BowPark
      Nov 22 at 13:03








    • 1




      It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
      – ctrl-alt-delor
      Nov 22 at 13:06










    • Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
      – xenoid
      Nov 22 at 14:41















    up vote
    3
    down vote










    up vote
    3
    down vote









    You can use Larry Wall's rename command (rename package in Debian, prename in RedHat): it uses the (much easier IMHO) Perl regex syntax, and will iterate the file args (no need to code a loop):



    rename 's/ (d+)/_$1/' name *





    share|improve this answer












    You can use Larry Wall's rename command (rename package in Debian, prename in RedHat): it uses the (much easier IMHO) Perl regex syntax, and will iterate the file args (no need to code a loop):



    rename 's/ (d+)/_$1/' name *






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 22 at 12:58









    xenoid

    2,6201724




    2,6201724












    • Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
      – BowPark
      Nov 22 at 13:03








    • 1




      It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
      – ctrl-alt-delor
      Nov 22 at 13:06










    • Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
      – xenoid
      Nov 22 at 14:41




















    • Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
      – BowPark
      Nov 22 at 13:03








    • 1




      It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
      – ctrl-alt-delor
      Nov 22 at 13:06










    • Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
      – xenoid
      Nov 22 at 14:41


















    Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
    – BowPark
    Nov 22 at 13:03






    Thank you, it seems very convenient. I wonder, however, if it is portable to other *nix systems (not only Linux).
    – BowPark
    Nov 22 at 13:03






    1




    1




    It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
    – ctrl-alt-delor
    Nov 22 at 13:06




    It is possible, just install it. It is a purl script. It has no dependencies on Linux (the kernel). However beware that there are other commands with the name rename, they are not the same. Some Unixes (including those using Linux), have another rename installed.
    – ctrl-alt-delor
    Nov 22 at 13:06












    Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
    – xenoid
    Nov 22 at 14:41






    Available wherever you have Perl, which is about any Unix system. On my Ubuntu I have prenameinstalled as part of the Perl package, and rename installed as stand-alone (not exactly the same code, even though the core is identical). On Redhat and derivatives there is already a (less powerfull, but easier) rename command, so you only have prename.
    – xenoid
    Nov 22 at 14:41












    up vote
    1
    down vote













    If you know the exact range, you can rename the files like this:



    for i in {10..99}; do mv "name ($i).ext" "name_$i.ext"; done


    Or, if you want to be POSIX-pedantic:



    for i in `seq 10 99`; do mv "name ($i).ext" "name_$i.ext"; done





    share|improve this answer

























      up vote
      1
      down vote













      If you know the exact range, you can rename the files like this:



      for i in {10..99}; do mv "name ($i).ext" "name_$i.ext"; done


      Or, if you want to be POSIX-pedantic:



      for i in `seq 10 99`; do mv "name ($i).ext" "name_$i.ext"; done





      share|improve this answer























        up vote
        1
        down vote










        up vote
        1
        down vote









        If you know the exact range, you can rename the files like this:



        for i in {10..99}; do mv "name ($i).ext" "name_$i.ext"; done


        Or, if you want to be POSIX-pedantic:



        for i in `seq 10 99`; do mv "name ($i).ext" "name_$i.ext"; done





        share|improve this answer












        If you know the exact range, you can rename the files like this:



        for i in {10..99}; do mv "name ($i).ext" "name_$i.ext"; done


        Or, if you want to be POSIX-pedantic:



        for i in `seq 10 99`; do mv "name ($i).ext" "name_$i.ext"; done






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 16:17









        Martin Frodl

        1893




        1893















            Popular posts from this blog

            What visual should I use to simply compare current year value vs last year in Power BI desktop

            How to ignore python UserWarning in pytest?

            Alexandru Averescu