linux - 根据conf文件替换文件的值

标签 linux perl shell unix configuration

我有一个conf文件,其格式为variable =“value”,其中值也可能具有特殊字符。示例行是:

LINE_D="(L#'id' == 'log') AND L#'id' 为 NULL"

我有另一个文件 F,它应该替换基于此 conf 文件的值。例如,如果 F 中有一行 打印“$LINE_D” 它应该被替换为 PRINT '(L#'id' == 'log') AND L#'id' 为 NULL'

如何在 shell 脚本中编写一个程序,该程序接受 conf 和 F 并生成替换的 F 中的值。

谢谢

最佳答案

您对所需内容的定义存在很多空白,因此您可能需要调整此脚本。它是最初设计用于处理 makefile 的更复杂脚本的精简版本。这意味着您可能可以从这里删除一些 Material 而不会造成麻烦,尽管我已经摆脱了大部分无关的处理。

#!usr/bin/env perl
#
# Note: this script can take input from stdin or from one or more files.
# For example, either of the following will work:
#   cat config file | setmacro
#   setmacro file

use strict;
use warnings;
use Getopt::Std;

# Usage:
# -b -- omit blank lines
# -c -- omit comments
# -d -- debug mode (verbose)
# -e -- omit the environment

my %opt;
my %MACROS;
my $input_line;

die "Usage: $0 [-bcde] [file ...]" unless getopts('bcde', \%opt);

# Copy environment into hash for MAKE macros
%MACROS = %ENV unless $opt{e};

my $rx_macro = qr/\${?([A-Za-z]\w*)}?/;     # Matches $PQR} but ideally shouldn't

# For each line in each file specified on the command line (or stdin by default)
while ($input_line = <>)
{
    chomp $input_line;
    do_line($input_line);
}

# Expand macros in given value
sub macro_expand
{
    my($value) = @_;
    print "-->> macro_expand: $value\n" if $opt{d};
    while ($value =~ $rx_macro)
    {
        print "Found macro = $1\n" if $opt{d};
        my($env) = $MACROS{$1};
        $env = "" unless defined $env;
        $value = $` . $env . $';
    }
    print "<<-- macro_expand: $value\n" if $opt{d};
    return($value);
}

# routine to recognize macros
sub do_line
{
    my($line) = @_;
    if ($line =~ /^\s*$/o)
    {
        # Blank line
        print "$line\n" unless $opt{b};
    }
    elsif ($line =~ /^\s*#/o)
    {
        # Comment line
        print "$line\n" unless $opt{c};
    }
    elsif ($line =~ /^\s*([A-Za-z]\w*)\s*=\s*(.*)\s*$/o)
    {
        # Macro definition
        print "Macro: $line\n" if $opt{d};
        my $lhs = $1;
        my $rhs = $2;
        $rhs = $1 if $rhs =~ m/^"(.*)"$/;
        $MACROS{$lhs} = ${rhs};
        print "##M: $lhs = <<$MACROS{$lhs}>>\n" if $opt{d};
    }
    else
    {
        print "Expand: $line\n" if $opt{d};
        $line = macro_expand($line);
        print "$line\n";
    }
}

给定一个配置文件,cfg,包含:

LINE_D="(L#'id' == 'log') AND L#'id' IS NULL"

和另一个文件,F,包含:

PRINT '$LINE_D'
PRINT '${LINE_D}'

perl setmacro.pl cfg F 的输出是:

PRINT '(L#'id' == 'log') AND L#'id' IS NULL'
PRINT '(L#'id' == 'log') AND L#'id' IS NULL'

这与所需的输出匹配,但给了我带有多个单引号的heebie-jeebies。然而,客户永远是对的!

(我认为我摆脱了残留的 Perl 4-isms;基本脚本仍然留下了一些残余,以及一些关于 Perl 5.001 如何以不同方式处理事物的评论。它确实使用了 $`$' 这通常不是一个好主意。但是它有效,所以修复它对读者来说是一个练习。正则表达式变量现在不是必需的;当时它还识别 make 宏符号 - $(macro) 以及 ${macro}.)

关于linux - 根据conf文件替换文件的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19456705/

相关文章:

perl - 如何计算 Perl 中重叠的子字符串?

调用守护进程的 Shell 脚本 - DAEMON : command not found

linux - 在 n 列中重新排列文件内容

java - 无法从 FTP 服务器下载文件

java - 从 bash 管理 Linux 中的进程/服务

java - 使用 Linux 为 Java 应用程序设置最大创建线程数

linux - romfs 包中的二进制所有权

Python 程序将在 Spyder 终端中运行,但不会在常规 linux 终端中运行

java - 从 Java 调用时 Perl 进程找不到命令 svn

arrays - Perl 将一个数组放入特定列的二维数组中