Terry, that would change 'latest-pkg-erlangen' into 'latest_pkg_erlangen" which isn't what I needed. I only wanted the first '-' to be changed into an underscore, and not all of them
Another approach is to use a numerical flag after the sed search and replacement. From sed(1)
Code:
[2addr]s/re/replacement/flags
[snip]
Th value of flags in the substitute function is zero or more
of the following:
0 ... 9
Make the substitution only for the N'th occur-
rence of the regular expression in the pattern
space.
That allows you to use things like this:
Code:
$ echo 12345678 | sed -e 's/./#/4'
123#5678
$ echo 12345678 | sed -e 's/../#/2'
12#5678
In the first example, the regular expression is '.', which stands for any character. the '2' flag causes only the second whatever character to be subsituted.
The regular expression from the last example is '..', or a group of two whatever characters. So here the second pair of numbers '34' is replaced by
a '#'.
A single filename like 'latest-pkg-plig' can be converted rather easily into a 'mv latest-pkg-plig latest-pkg-plig'.
To turn this intermediate result into a meaningful mv command, we only have to change the second occurrence of '-pkg' into '_pkg'.
The first transformation and the explanation:
Code:
$ echo latest-pkg-plig | sed -e 's/^.*$/mv & & /'
mv latest-pkg-plig latest-pkg-plig
# ----------------------------------------------------
s : search and replace
/ : delimiter marking start of search
^ : beginning of line
. : whatever character
* : zero or more of the preceding atom
$ : end of line
/ : end of search pattern, start of replacement
mv : a 'm', 'v', and a blank
& : the matched searched pattern
: a space
& : the matched search pattern
: a space
/ : end of replacement
The last and final transformation:
Code:
echo mv latest-pkg-plig latest-pkg-plig | sed -e 's/-pkg/_pkg/2'
mv latest-pkg-plig latest_pkg-plig
# -------------------------------
s : search and replace
/ : delimiter marking start of search
-pkg : a sequence of '-', 'p', 'k', and 'g'
/ : end of search pattern, start of replacement
_pkg : a '-', 'p', 'k' and a 'g'
/ : end of replacement
2 : only act on second occurence
Applying both transformations to some file names in file tmp:
Code:
sed -e 's/^.*$/mv & & /' -e 's/-pkg/_pkg/2' tmp
mv NOW/latest-pkg NOW/latest_pkg
mv NOW/latest-pkg-erlangen NOW/latest_pkg-erlangen
mv NOW/latest-pkg-plig NOW/latest_pkg-plig
Actually my directory names were much longer and they already had hyphens in them. Applying these regexes to such a directory I still had an original backup of
Code:
$ ls Snap2008-07-12_23.47_UTC/*-pkg* | sed -e 's/^.*$/mv & & /' -e 's/-pkg/_pkg/2'
mv Snap2008-07-12_23.47_UTC/latest-pkg Snap2008-07-12_23.47_UTC/latest_pkg
mv Snap2008-07-12_23.47_UTC/latest-pkg-arctic Snap2008-07-12_23.47_UTC/latest_pkg-arctic
mv Snap2008-07-12_23.47_UTC/latest-pkg-calyx Snap2008-07-12_23.47_UTC/latest_pkg-calyx
mv Snap2008-07-12_23.47_UTC/latest-pkg-plig Snap2008-07-12_23.47_UTC/latest_pkg-plig
As you can see this really was worth to be automated