¿Cómo cambiar el nombre de archivos por lotes con el comando de cambio de nombre de Unix?

¿Cómo cambiar el nombre de archivos por lotes con el comando de cambio de nombre de Unix?

Tengo archivos cuyos nombres se ven así:

Sim1-2_40.36.chr20_sb.foo.indel.novoalign.sam
Sim1-2_40.36.chr20_sb.foo.indel.bwa.sam

Lo que quiero hacer es reemplazar todos indelcon snplos nombres que dan

Sim1-2_40.36.chr20_sb.foo.snp.novoalign.sam
Sim1-2_40.36.chr20_sb.foo.snp.bwa.sam

Pero ¿por qué no funciona este comando de Unix?

$ rename 's/indel/snp/' *.sam

Respuesta1

Porque estás usando el programa de cambio de nombre incorrecto. Este es el correcto.

Respuesta2

La utilidad "normal" rename(parte de util-linux) toma 3 o más argumentos (como se menciona en TFM...)

rename FROM TO filespec...

Por lo tanto, usted (probablemente) está buscando:

rename .indel. .snp. *.sam

Pruebe esto primero en un directorio temporal, ya que es posible que esté utilizando otra implementación de rename.

O consulte la página de manual. tos

Respuesta3

ls -1 | while read item
do
  mv $item $(echo $item|sed -e s/.indel./.snp./g);
done

Respuesta4

renameno hace sedsustituciones de estilo. Este breve script en Perl te permitirá hacer regmv *.sam s/indel/snp/:

#!/usr/bin/perl -w
#
# regmv - Rename files using a regular expression
#
# This program renames files by using a regular expression to
# determine their new name.
#
# Usage: regmv file [file ...] regexp
#
# $Id: regmv,v 1.1 1998/10/14 17:07:55 blrfl Exp $
#

sub at_clean()
{
    my $message = $@;
    $message =~ s|\s+at /.*$||s;
    return $message;
}

(@ARGV > 1)
    || die "Usage: regmv [options] file [file ...] regexp\n";

my $expr = pop @ARGV;

$_ = 'SomeValue';
eval "\$_ =~ $expr";
die "Yuck: " . at_clean() if $@;

foreach (@ARGV)
{
    my $old = $_;

    eval "\$_ =~ $expr";

    next if $_ eq $old;

    (rename $old, $_)
        || die "Rename failed: $!\n";
}

información relacionada