开发者

editing text files with perl

I'm trying to edit a text file that looks like this:

TYPE=Ethernet
HWADDR=00:....
IPV6INIT=开发者_StackOverflow社区no
MTU=1500
IPADDR=192.168.2.247
...

(Its actually the /etc/sysconfig/network-scripts/ifcfg- file on red hat Linux) Instead of reading and rewriting the file each time I want to modify it, I figured I could use grep, sed, awk or the native text parsing functionality provided in Perl.

For instance, if I wanted to change the IPADDR field of the file, is there a way I can just retrieve and modify the line directly? Maybe something like

grep 'IPADDR=' <filename> 

but add some additional arguments to modify that line? I'm a little new to UNIX based text processing languages so bear with me...

Thanks!


Here's a Perl oneliner to replace the IPADDR value with the IP address 127.0.01. It's short enough that you should be able to see what you need to modify to alter other fields*:

perl -p -i.orig -e 's/^IPADDR=.*$/IPADDR=127.0.0.1/' filename

It will rename "filename" to "filename.orig", and write out the new version of the file into "filename".

Perl command-line options are explained at perldoc perlrun (thanks for the reminder toolic!), and the syntax of perl regular expressions is at perldoc perlre.

*The regular expression ^IPADDR=.*$, split into components, means:

  ^         # bind to the beginning of the line
  IPADDR=   # plain text: match "IPADDR="
  .*        # followed by any number of any character (`.` means "any one character"; `*` means "any number of them")
  $         # bind to the end of the line


since you are on redhat, you can try using the shell

#!/bin/bash

file="file"
read -p "Enter field to change: " field
read -p "Enter new value: " newvalue
shopt -s nocasematch
while IFS="=" read -r f v
do
    case "$f" in
        $field)
            v=$newvalue;;
    esac
    echo "$f=$v"
done <$file > temp
mv temp file

UPDATE:

file="file"
read -p "Enter field to change: " field
read -p "Enter new value: " newvalue
shopt -s nocasematch
EOL=false
IFS="="
until $EOL
do
    read -r f v || EOL=true
    case "$f" in
        $field)
            v=$newvalue;;
    esac
    echo "$f=$v"
done <$file #> temp
#mv temp file

OR , using just awk

awk 'BEGIN{
    printf "Enter field to change: "
    getline field < "-"
    printf "Enter new value: "
    getline newvalue <"-"
    IGNORECASE=1
    OFS=FS="="
}
field == $1{
    $2=newvalue
}
{
    print $0 > "temp"
}END{
    cmd="mv temp "FILENAME
    system(cmd)
}'  file

Or with Perl

printf "Enter field: ";
chomp($field=<STDIN>);
printf "Enter new value: ";
chomp($newvalue=<STDIN>);
while (<>){
    my ( $f , $v ) = split /=/;
    if ( $field =~ /^$f/i){
        $v=$newvalue;
    }
    print join("=",$f,$v);
}


That would be the 'ed' command line editor, like sed but will put the file back where it came from.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜