Ersetzen Sie die gesamte Zeile in einer Datei über die Befehlszeile

Ersetzen Sie die gesamte Zeile in einer Datei über die Befehlszeile

Ich habe eine Textdatei mit ähnlichem Inhalt wie dieser:

# 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'

Ich möchte die version = '0.5'Zeile durch „ version = Xwobei X ein an ein Skript übergebenes Befehlszeilenargument ist“ ersetzen und dann dasselbe für die release =Zeile tun.

Gibt es einen einfachen Befehl, den ich aufrufen kann, um diese Art der Ersetzung durchzuführen? Ich habe mich sedein wenig damit befasst, aber es scheint, dass die globale Ersetzung in sed erfordern würde, dass ich nach suche version = '0.5', aber alles, was ich wirklich suchen möchte, ist eine Zeile, die mit version =- beginnt, da ich keine Ahnung habe, welche Version es sein könnte, wenn ich das Skript ausführe!

Irgendwelche Ideen?

Antwort1

sed -i "/^version =/s/'[^']*'/'NEW_VERSION_IS_HERE'/" your_file

Antwort2

Eine Möglichkeit mit perl:

Angenommen, infilees handelt sich um Inhalte, die Sie in Ihre Frage eingefügt haben.

Inhalt von 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], $_; 
}

Führen Sie es wie folgt aus:

perl script.pl infile --version=1.3 --release=2.6

Mit folgender Ausgabe:

# 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'

Antwort3

Wenn $Xder Parameter ist, in dem die neue Version gespeichert wird,

ed file << EOF
g/^version =/s/.*/version = '$X'/
g/^release =/s/.*/release = '$X'/
w
q
EOF

Dies setzt $Xeinen sinnvollen Wert voraus, etwa , und keine Zeichen, die für den Befehlsinterpreter 1.2.3-foospeziell sind .ed

Antwort4

Als Shell-Skript:

#!/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

Dies ist nur ein kurzes Beispiel. Es führt keine Fehlerprüfung durch und sichert die Originaldatei nicht für den Fall, dass eine der Ausgabeumleitungen sie löscht und Sie mit einer leeren Datei zurücklassen. Ich sage, verwenden Sie dies nicht in der Produktion, aber es gibt Ihnen eine Vorstellung davon, wie Sie das tun können, was Sie versuchen zu tun.

verwandte Informationen