2010-02-03 7 views
1

Я пытаюсь редактировать текстовый файл, который выглядит следующим образом:редактирование текстовых файлов с Perl

TYPE=Ethernet 
HWADDR=00:.... 
IPV6INIT=no 
MTU=1500 
IPADDR=192.168.2.247 
... 

(его на самом деле и т.д./sysconfig/сети-скрипты/ifcfg- файл/на Red Hat Linux) Вместо чтения и перезаписи файла каждый раз, когда я хочу его изменить, я решил, что могу использовать grep, sed, awk или собственные функции синтаксического анализа текста, представленные на Perl.

Например, если я хотел изменить поле IPADDR файла, есть ли способ, которым я могу просто получить и изменить строку напрямую? Может быть, что-то вроде

grep 'IPADDR=' <filename> 

но добавить некоторые дополнительные аргументы для изменения этой строки? Я немного новичок в языках обработки текста на основе UNIX, поэтому несите меня ...

Спасибо!

ответ

8

Это Perl oneliner, чтобы заменить значение IPADDR на IP-адрес 127.0.01. Это достаточно мало, что вы должны быть в состоянии увидеть, что вам нужно изменить, чтобы изменить другие поля *:

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

Это будет переименовать «имя файла» в «filename.orig», и написать новую версию файла в "filename".

Параметры командной строки в Perl объясняются в perldoc perlrun (спасибо за инструмент напоминания!), А синтаксис регулярных выражений perl - perldoc perlre.

* Регулярное выражение ^IPADDR=.*$, разделить на составные части, означает:

^  # 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 
+0

... и OP может найти смысл этих переключателей perl' из командной строки: 'perldoc perlrun' – toolic

+0

спасибо за напоминание; хорошо всегда предоставлять ссылку для получения дополнительной информации! – Ether

0

Это будет редактор командной строки 'ed', например sed, но вернет файл туда, откуда он появился.

2

, так как вы находитесь на RedHat, вы можете попробовать использовать скорлупу

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

ИЛИ, используя только 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 

Или с 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); 
} 
+0

Спасибо за ваши подробные ответы! Сценарий bash выполняет именно то, что мне нужно, за исключением того, что удаляет последнюю строку, когда файл перезаписывается. Нужно ли просто добавлять EOF в цикл while или что бы вы предложили? –

+0

Это странно. У меня нет проблем с этим. PLS попробуйте «новую» версию, которую я редактировал. – ghostdog74

 Смежные вопросы

  • Нет связанных вопросов^_^