Skip to main content
Commonmark migration
Source Link

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).  I’ll suppose that you have a bunch of files whose names include the words “over” and “dog”, and you want to replace them with “under” and “cat”, respectively.

###Brute force:

Brute force:

for f in *
do
    g=${f/over/under}
    h=${g/dog/cat}
    mv -- "$f" "$h"
done

(The -- protects you against undesired behavior that could result from a filename that begins with -.  Change the last line to mv -- "$f" "$h".jpg if you want.)  Note that, if a filename contains only “over” or “dog” (but not both), this will do just the one available substitution.  If it contains “dog” and “over” (in that order), it will still do the substitutions.  In the case you presented, where your strings are “(“ and “)”, you might not like these behaviors.

P.S. Realistically, you should probably protect the mv command like this:

if [ "$f" != "$h" ]
then
    if [ -e "$h" ]
    then
        (Error handling)
    else
        mv -- "$f" "$h"
    fi
done

to avoid getting an error message when you try to rename a file to itself (because its name didn’t contain either of the strings), and to avoid clobbering an existing file (e.g., if you have an image(1) file and you also already have an image1.jpg file).

###with sed

with sed

for f in *
do
    g=$(sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/' <<< "$f")
    mv -- "$f" "$g"
done

This is the opposite of the first one: it does the substitutions only if “over” and “dog” both appear (in that order) and not otherwise.

The <<< (“here string”) syntax doesn’t work in all shells.  To do the above in a shell that doesn’t support here strings, do:

for f in *
do
    g=$(printf "%s" "$f" | sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/')
    mv -- "$f" "$g"
done

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).  I’ll suppose that you have a bunch of files whose names include the words “over” and “dog”, and you want to replace them with “under” and “cat”, respectively.

###Brute force:

for f in *
do
    g=${f/over/under}
    h=${g/dog/cat}
    mv -- "$f" "$h"
done

(The -- protects you against undesired behavior that could result from a filename that begins with -.  Change the last line to mv -- "$f" "$h".jpg if you want.)  Note that, if a filename contains only “over” or “dog” (but not both), this will do just the one available substitution.  If it contains “dog” and “over” (in that order), it will still do the substitutions.  In the case you presented, where your strings are “(“ and “)”, you might not like these behaviors.

P.S. Realistically, you should probably protect the mv command like this:

if [ "$f" != "$h" ]
then
    if [ -e "$h" ]
    then
        (Error handling)
    else
        mv -- "$f" "$h"
    fi
done

to avoid getting an error message when you try to rename a file to itself (because its name didn’t contain either of the strings), and to avoid clobbering an existing file (e.g., if you have an image(1) file and you also already have an image1.jpg file).

###with sed

for f in *
do
    g=$(sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/' <<< "$f")
    mv -- "$f" "$g"
done

This is the opposite of the first one: it does the substitutions only if “over” and “dog” both appear (in that order) and not otherwise.

The <<< (“here string”) syntax doesn’t work in all shells.  To do the above in a shell that doesn’t support here strings, do:

for f in *
do
    g=$(printf "%s" "$f" | sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/')
    mv -- "$f" "$g"
done

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).  I’ll suppose that you have a bunch of files whose names include the words “over” and “dog”, and you want to replace them with “under” and “cat”, respectively.

Brute force:

for f in *
do
    g=${f/over/under}
    h=${g/dog/cat}
    mv -- "$f" "$h"
done

(The -- protects you against undesired behavior that could result from a filename that begins with -.  Change the last line to mv -- "$f" "$h".jpg if you want.)  Note that, if a filename contains only “over” or “dog” (but not both), this will do just the one available substitution.  If it contains “dog” and “over” (in that order), it will still do the substitutions.  In the case you presented, where your strings are “(“ and “)”, you might not like these behaviors.

P.S. Realistically, you should probably protect the mv command like this:

if [ "$f" != "$h" ]
then
    if [ -e "$h" ]
    then
        (Error handling)
    else
        mv -- "$f" "$h"
    fi
done

to avoid getting an error message when you try to rename a file to itself (because its name didn’t contain either of the strings), and to avoid clobbering an existing file (e.g., if you have an image(1) file and you also already have an image1.jpg file).

with sed

for f in *
do
    g=$(sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/' <<< "$f")
    mv -- "$f" "$g"
done

This is the opposite of the first one: it does the substitutions only if “over” and “dog” both appear (in that order) and not otherwise.

The <<< (“here string”) syntax doesn’t work in all shells.  To do the above in a shell that doesn’t support here strings, do:

for f in *
do
    g=$(printf "%s" "$f" | sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/')
    mv -- "$f" "$g"
done
Post Undeleted by G-Man Says 'Reinstate Monica'
Bang.
Source Link

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although although this may be applicable to other contexts).  I’ll suppose that you have a bunch of files whose names include the words “over” and “dog”, and you want to replace them with “under” and “cat”, respectively.

###Brute force:

for f in *
do
    g=${f/over/under}
    h=${g/dog/cat}
    mv -- "$f" "$h"
done

(The -- protects you against undesired behavior that could result from a filename that begins with -.  Change the last line to mv -- "$f" "$h".jpg if you want.)  Note that, if a filename contains only “over” or “dog” (but not both), this will do just the one available substitution.  If it contains “dog” and “over” (in that order), it will still do the substitutions.  In the case you presented, where your strings are “(“ and “)”, you might not like these behaviors.

P.S. Realistically, you should probably protect the mv command like this:

if [ "$f" != "$h" ]
then
    if [ -e "$h" ]
    then
        (Error handling)
    else
        mv -- "$f" "$h"
    fi
done

to avoid getting an error message when you try to rename a file to itself (because its name didn’t contain either of the strings), and to avoid clobbering an existing file (e.g., if you have an image(1) file and you also already have an image1.jpg file).

###with sed

for f in *
do
    g=$(sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/' <<< "$f")
    mv -- "$f" "$g"
done

This is the opposite of the first one: it does the substitutions only if “over” and “dog” both appear (in that order) and not otherwise.

The <<< (“here string”) syntax doesn’t work in all shells.  To do the above in a shell that doesn’t support here strings, do:

for f in *
do
    g=$(printf "%s" "$f" | sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/')
    mv -- "$f" "$g"
done

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).  I’ll suppose that you have a bunch of files whose names include the words “over” and “dog”, and you want to replace them with “under” and “cat”, respectively.

###Brute force:

for f in *
do
    g=${f/over/under}
    h=${g/dog/cat}
    mv -- "$f" "$h"
done

(The -- protects you against undesired behavior that could result from a filename that begins with -.  Change the last line to mv -- "$f" "$h".jpg if you want.)  Note that, if a filename contains only “over” or “dog” (but not both), this will do just the one available substitution.  If it contains “dog” and “over” (in that order), it will still do the substitutions.  In the case you presented, where your strings are “(“ and “)”, you might not like these behaviors.

P.S. Realistically, you should probably protect the mv command like this:

if [ "$f" != "$h" ]
then
    if [ -e "$h" ]
    then
        (Error handling)
    else
        mv -- "$f" "$h"
    fi
done

to avoid getting an error message when you try to rename a file to itself (because its name didn’t contain either of the strings), and to avoid clobbering an existing file (e.g., if you have an image(1) file and you also already have an image1.jpg file).

###with sed

for f in *
do
    g=$(sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/' <<< "$f")
    mv -- "$f" "$g"
done

This is the opposite of the first one: it does the substitutions only if “over” and “dog” both appear (in that order) and not otherwise.

The <<< (“here string”) syntax doesn’t work in all shells.  To do the above in a shell that doesn’t support here strings, do:

for f in *
do
    g=$(printf "%s" "$f" | sed 's/\(.*\)over\(.*\)dog\(.*\)/\1under\2cat\3/')
    mv -- "$f" "$g"
done
Post Deleted by G-Man Says 'Reinstate Monica'
Source Link

I’ll address your general question of how to do multiple substitutions (specifically, in a rename, although this may be applicable to other contexts).