rename: add --all and --last parameters
Renaming files with rename often involves multiple passes in order to, say, replace all spaces with underscores because traditionally rename only replaces the first occurrence of the expression. The --all parameter makes this task simple. With the addition of --last, rename becomes much safer to use when replacing file extensions, whereas before it would mangle a file which had its extension also embedded elsewhere in its name. The implied --first, together with --all and --last, round out the common cases for renaming files.
This commit is contained in:
parent
be199d34f2
commit
a2b23d3a91
|
@ -11,7 +11,7 @@ _rename_module()
|
|||
esac
|
||||
case $cur in
|
||||
-*)
|
||||
OPTS="--verbose --symlink --help --version --no-act --no-override --interactive"
|
||||
OPTS="--verbose --symlink --help --version --no-act --all --last --no-override --interactive"
|
||||
COMPREPLY=( $(compgen -W "${OPTS[*]}" -- $cur) )
|
||||
return 0
|
||||
;;
|
||||
|
|
|
@ -31,6 +31,12 @@ Show which files were renamed, if any.
|
|||
*-n*, *--no-act*::
|
||||
Do not make any changes; add *--verbose* to see what would be made.
|
||||
|
||||
*-a*, *--all*::
|
||||
Replace all occurrences of _expression_ rather than only the first one.
|
||||
|
||||
*-l*, *--last*::
|
||||
Replace the last occurrence of _expression_ rather than the first one.
|
||||
|
||||
*-o*, *--no-overwrite*::
|
||||
Do not overwrite existing files. When *--symlink* is active, do not overwrite symlinks pointing to existing targets.
|
||||
|
||||
|
|
|
@ -44,23 +44,39 @@ for i in $@; do N=`echo "$i" | sed "s/$FROM/$TO/g"`; mv "$i" "$N"; done
|
|||
#define RENAME_EXIT_UNEXPLAINED 64
|
||||
|
||||
static int tty_cbreak = 0;
|
||||
static int all = 0;
|
||||
static int last = 0;
|
||||
|
||||
static int string_replace(char *from, char *to, char *s, char *orig, char **newname)
|
||||
{
|
||||
char *p, *q, *where;
|
||||
int count = 0, fromlen = strlen(from);
|
||||
|
||||
where = strstr(s, from);
|
||||
p = where = strstr(s, from);
|
||||
if (where == NULL)
|
||||
return 1;
|
||||
count++;
|
||||
while ((all || last) && p) {
|
||||
p = strstr(p + (last ? 1 : fromlen), from);
|
||||
if (p) {
|
||||
if (all)
|
||||
count++;
|
||||
if (last)
|
||||
where = p;
|
||||
}
|
||||
}
|
||||
p = orig;
|
||||
*newname = xmalloc(strlen(orig) + strlen(to) + 1);
|
||||
*newname = xmalloc(strlen(orig) - count * fromlen + count * strlen(to) + 1);
|
||||
q = *newname;
|
||||
while (p < where)
|
||||
*q++ = *p++;
|
||||
p = to;
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
p = where + strlen(from);
|
||||
while (where) {
|
||||
while (p < where)
|
||||
*q++ = *p++;
|
||||
p = to;
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
p = where + fromlen;
|
||||
where = strstr(p, from);
|
||||
}
|
||||
while (*p)
|
||||
*q++ = *p++;
|
||||
*q = 0;
|
||||
|
@ -226,6 +242,8 @@ static void __attribute__((__noreturn__)) usage(void)
|
|||
fputs(_(" -v, --verbose explain what is being done\n"), out);
|
||||
fputs(_(" -s, --symlink act on the target of symlinks\n"), out);
|
||||
fputs(_(" -n, --no-act do not make any changes\n"), out);
|
||||
fputs(_(" -a, --all replace all occurrences\n"), out);
|
||||
fputs(_(" -l, --last replace only the last occurrence\n"), out);
|
||||
fputs(_(" -o, --no-overwrite don't overwrite existing files\n"), out);
|
||||
fputs(_(" -i, --interactive prompt before overwrite\n"), out);
|
||||
fputs(USAGE_SEPARATOR, out);
|
||||
|
@ -246,6 +264,8 @@ int main(int argc, char **argv)
|
|||
{"verbose", no_argument, NULL, 'v'},
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{"all", no_argument, NULL, 'a'},
|
||||
{"last", no_argument, NULL, 'l'},
|
||||
{"no-act", no_argument, NULL, 'n'},
|
||||
{"no-overwrite", no_argument, NULL, 'o'},
|
||||
{"interactive", no_argument, NULL, 'i'},
|
||||
|
@ -258,11 +278,19 @@ int main(int argc, char **argv)
|
|||
textdomain(PACKAGE);
|
||||
close_stdout_atexit();
|
||||
|
||||
while ((c = getopt_long(argc, argv, "vsVhnoi", longopts, NULL)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "vsVhnaloi", longopts, NULL)) != -1)
|
||||
switch (c) {
|
||||
case 'n':
|
||||
noact = 1;
|
||||
break;
|
||||
case 'a':
|
||||
all = 1;
|
||||
last = 0;
|
||||
break;
|
||||
case 'l':
|
||||
last = 1;
|
||||
all = 0;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
|
|
|
@ -2,3 +2,17 @@
|
|||
`rename_basic.2' -> `rename_test.2'
|
||||
`rename_basic.3' -> `rename_test.3'
|
||||
what is rename_basic.? doing here?
|
||||
`rename_all file with spaces.1' -> `rename_all_file_with_spaces.1'
|
||||
`rename_all file with spaces.2' -> `rename_all_file_with_spaces.2'
|
||||
`rename_all file with spaces.3' -> `rename_all_file_with_spaces.3'
|
||||
what is rename_all* *.? doing here?
|
||||
`rename_zz_last_z.x' -> `rename_AAzzBB_last_z.x'
|
||||
`rename_zz_last_z.y' -> `rename_AAzzBB_last_z.y'
|
||||
`rename_zz_last_z.z' -> `rename_AAzzBB_last_z.z'
|
||||
`rename_zz_last_zz.x' -> `rename_zz_last_AAzzBB.x'
|
||||
`rename_zz_last_zz.y' -> `rename_zz_last_AAzzBB.y'
|
||||
`rename_zz_last_zz.z' -> `rename_zz_last_AAzzBB.z'
|
||||
`rename_zz_last_zzz.x' -> `rename_zz_last_zAAzzBB.x'
|
||||
`rename_zz_last_zzz.y' -> `rename_zz_last_zAAzzBB.y'
|
||||
`rename_zz_last_zzz.z' -> `rename_zz_last_zAAzzBB.z'
|
||||
what is rename*last* doing here?
|
||||
|
|
|
@ -38,4 +38,34 @@ for i in rename_test.{1..3}; do
|
|||
fi
|
||||
done
|
||||
|
||||
|
||||
touch rename_all\ file\ with\ spaces.{1..3}
|
||||
$TS_CMD_RENAME -v -a ' ' '_' rename_all*.? >> $TS_OUTPUT 2> $TS_ERRLOG
|
||||
|
||||
for i in rename_all*\ *.?; do
|
||||
echo "what is $i doing here?" >> $TS_OUTPUT
|
||||
done
|
||||
for i in rename_all_file_with_spaces.{1..3}; do
|
||||
if [ ! -f $i ]; then
|
||||
echo "file $i is missing" >> $TS_OUTPUT
|
||||
else
|
||||
rm -f $i
|
||||
fi
|
||||
done
|
||||
|
||||
touch rename_zz_last_{z,z{,z{,z}}}.{x..z}
|
||||
$TS_CMD_RENAME -v -l zz AAzzBB rename_zz_last_* >> $TS_OUTPUT 2> $TS_ERRLOG
|
||||
for i in rename_AAzzBB_last_z.x rename_AAzzBB_last_z.y rename_AAzzBB_last_z.z \
|
||||
rename_zz_last_AAzzBB.x rename_zz_last_AAzzBB.y rename_zz_last_AAzzBB.z \
|
||||
rename_zz_last_zAAzzBB.x rename_zz_last_zAAzzBB.y rename_zz_last_zAAzzBB.z ; do
|
||||
if [ ! -f $i ]; then
|
||||
echo "file $i is missing" >> $TS_OUTPUT
|
||||
else
|
||||
rm -f $i
|
||||
fi
|
||||
done
|
||||
for i in rename*last* ; do
|
||||
echo "what is $i doing here?" >> $TS_OUTPUT
|
||||
done
|
||||
|
||||
ts_finalize
|
||||
|
|
Loading…
Reference in New Issue