Tengo un archivo de texto que tiene un contenido similar a este:
# General information about the project.
project = u'Py6S'
copyright = u'2012, Robin Wilson'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '0.5'
# The full version, including alpha/beta/rc tags.
release = '0.5'
Me gustaría reemplazar la version = '0.5'
línea version = X
donde X es un argumento de línea de comando dado a un script y luego hacer lo mismo con la release =
línea.
¿Existe algún comando simple al que pueda llamar para realizar este tipo de reemplazo? Lo he investigado sed
un poco, pero parece que la sustitución global en sed requeriría que buscara version = '0.5'
, pero todo lo que realmente quiero buscar es una línea que comience con version =
, ya que no tengo idea de cuál podría ser la versión cuando ejecuta el script!
¿Algunas ideas?
Respuesta1
sed -i "/^version =/s/'[^']*'/'NEW_VERSION_IS_HERE'/" your_file
Respuesta2
Una forma usando perl
:
Suponiendo que infile
tenga contenido que haya pegado en su pregunta.
Contenido de script.pl
:
use warnings;
use strict;
use Getopt::Long;
## Check arguments.
die qq[Usage: perl $0 <file> [--version=<num>] [--release=<num>]\n] unless @ARGV > 1;
my ($version, $release);
## Get value of arguments.
GetOptions(
q[version=f] => \$version,
q[release=f] => \$release,
) or die qq[ERROR: Bad input arguments\n];
## Sanity check.
exit 0 if ! defined $version && ! defined $release;
## Read input file line by line, and substitute values of 'version' and 'release'
## when matched.
while ( <> ) {
chomp;
s/\A((?i:version)\s*=\s*')([^']+)(?=')/$1 . (defined $version ? $version : $2)/e;
s/\A((?i:release)\s*=\s*')([^']+)(?=')/$1 . (defined $release ? $release : $2)/e;
printf qq[%s\n], $_;
}
Ejecútelo como:
perl script.pl infile --version=1.3 --release=2.6
Con la siguiente salida:
# General information about the project.
project = u'Py6S'
copyright = u'2012, Robin Wilson'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = '1.3'
# The full version, including alpha/beta/rc tags.
release = '2.6'
Respuesta3
Si $X
es el parámetro donde se almacena la nueva versión,
ed file << EOF
g/^version =/s/.*/version = '$X'/
g/^release =/s/.*/release = '$X'/
w
q
EOF
Esto supone $X
que tiene un valor razonable, como 1.2.3-foo
y que no hay caracteres especiales para el ed
intérprete de comandos.
Respuesta4
Como script de shell:
#!/bin/ksh
function usage {
echo
echo "Usage: $0 <file> <version> <release>"
echo
exit 1
}
function update_version {
cat $file | sed -e "s/^version.*$/version = \'$version\'/" > $file.new
mv $file.new $file
}
function update_release {
cat $file | sed -e "s/^release.*$/release = \'$release\'/" > $file.new
mv $file.new $file
}
file=$1
version=$2
release=$3
if [ ! -f $file ]; then
usage
fi
if [ $# != 3 ]; then
usage
fi
update_version
update_release
Este es sólo un ejemplo rápido. No realiza ninguna verificación de errores y no realiza una copia de seguridad del archivo original en el caso de que una de las redirecciones de salida lo borre y lo deje con un archivo vacío. Lo que estoy diciendo es que no uses esto en producción, pero te dará una idea de cómo hacer lo que estás intentando hacer.