2

我需要在文件“cfg_file”中搜索多行文本并将该文本替换为另一个文本。要搜索的文本在“cfg_name”中,替换文本在“cfg_value”中。我正在使用 ubuntu m/c。

cfg_file:

rem01=("LOG_CHAN01_REM_IP" transport("tcp") port( LOG_CHAN01_REM_PORT ) );
rem02=("LOG_CHAN02_REM_IP" transport("tcp") port( LOG_CHAN02_REM_PORT ) ); 

cfg_name:

LOG_CHAN01_REM_IP
LOG_CHAN01_REM_PORT
LOG_CHAN02_REM_IP
LOG_CHAN02_REM_PORT

cfg_value:

10.123.122.52
50001
10.15.19.51
50002

我使用了下面的脚本(从网络上的一些早期查询中得到它),但没有按预期工作。任何想法???

awk 'BEGIN { RS="" } 
FILENAME==ARGV[1] { s=$0 }
FILENAME==ARGV[2] { r=$0 }
FILENAME==ARGV[3] { sub(s,r); print }
END { print NR, "Students Records are processed." }
' ./cfg_name ./cfg_value ./cfg_file > ./outfile
4

4 回答 4

3

AWK Solution

There are better tools to do this. However, if you insist in awk:

FILENAME == ARGV[1] {
    name[FNR] = $0
}

FILENAME == ARGV[2] {
    value[name[FNR]] = $0
}

FILENAME == ARGV[3] && FNR <= 20000 {
    for (n in value) {
        gsub(n, value[n]);
    }
    print
}

M4 Solution

As Catcall suggested, we can use m4:

#!/bin/bash
# Script's arguments: cfg_name cfg_value cfg_file
{
    paste $1 $2 | while read name value
    do
        echo "define(\`${name}', \`${value}')"
    done
    cat $3
} | m4
echo "$(wc -l $3) Students Records are processed."
于 2013-01-23T15:25:17.483 回答
2

另一个 awk 版本,只有一个循环来读取变量:

BEGIN {
  # Read all variables in VAR_TABLE
  while( ( getline VAR < cfg_name ) > 0 ) {
    if ( ( getline VALUE < cfg_value ) > 0 ) {
      VAR_TABLE[ VAR ] = VALUE
    } else {
      print "ERROR: no value for " VAR > "/dev/stderr"
    }
  }
}

{
   # Convert all lines
   for ( VAR in VAR_TABLE ) { gsub( VAR, VAR_TABLE[ VAR ] ) }
   print
}
于 2013-01-23T19:44:28.753 回答
1

正确的方法是首先读取 2 个文件(名称和值),然后将替换应用到 cfg_file。

AWK 代码是:

#!/usr/bin/awk -f
BEGIN {
    file = ARGV[1];
    name = ARGV[2];
    value = ARGV[3];
    ARGC = 2;
    i = 1;
    while ( (getline < name) > 0 ) {
        names[i] = $1;
        i++;
    }
    i = 1;
    while ( (getline < value) > 0 ) {
        values[i] = $1;
        i++;
    }
}
{
    for ( i in names ) {
        sub( names[i], values[i], $0 );
    }
    print $0;
}
END {
    print NR" Students Records are processed.";
}

我将代码保存到merge.awk您可以通过这种方式调用的代码:

awk -f merge.awk ./cfg_file ./cfg_name ./cfg_value

输出是:

rem01=("10.123.122.52" transport("tcp") port( 50001 ) );
rem02=("10.15.19.51" transport("tcp") port( 50002 ) );
于 2013-01-23T15:32:15.267 回答
1

解决方案是否必须在 AWK 中?

这是一些可以帮助您入门的python代码...将其保存到文件“replace.py”中,然后运行它。我插入了您在问题中指定的文件名。

substitution_dict = {}
name_file = open("cfg_name","r")
value_file = open("cfg_value","r")
for line in name_file.readlines():
    name = line.strip()
    value = value_file.readline().strip()
    substitution_dict[name]=value

for line in open("cfg_file","r").readlines():
    line = line.strip()
    for name in substitution_dict.keys():
        line = line.replace(name, substitution_dict[name])
    print line
于 2013-01-23T15:12:09.130 回答