用另一个文件中指定的值替换字段

use*_*630 3 shell awk sed

我有一个文件,其中包含单词之间的映射.我必须引用该文件,并将这些单词替换为某些文件中的映射单词.例如,下面的文件具有映射的单词表

1.12.2.4               1
1.12.2.7               12
1.12.2.2               5
1.12.2.4               4
1.12.2.6               67
1.12.2.12              5
Run Code Online (Sandbox Code Playgroud)

我将有许多具有这些关键词的文件(1.12.2.*).我想搜索这些关键词,并将这些词替换为从该文件中获取的相应映射.如何在shell中执行此操作.假设一个文件包含以下行说

The Id of the customer is 1.12.2.12. He is from Grg. 
The Name of the machine is ASB
The id is 1.12.2.4. He is from Psg.
Run Code Online (Sandbox Code Playgroud)

执行脚本后,数字"1.12.2.12"和"1.12.2.4"应替换为5和4(从主文件中引用).谁能帮我吗?

Ste*_*eve 5

一种方式使用GNU awk:

awk 'FNR==NR { array[$1]=$2; next } { for (i in array) gsub(i, array[i]) }1' master.txt file.txt
Run Code Online (Sandbox Code Playgroud)

结果:

The Id of the customer is 5. He is from Grg.
The Name of the machine is ASB
The id is 4. He is from Psg.
Run Code Online (Sandbox Code Playgroud)

要将输出保存到文件:

awk 'FNR==NR { array[$1]=$2; next } { for (i in array) gsub(i, array[i]) }1' master.txt file.txt > name_of_your_output_file.txt
Run Code Online (Sandbox Code Playgroud)

说明:

FNR==NR { ... }   # FNR is the current record number, NR is the record number
                  # so FNR==NR simply means: "while we process the first file listed
                  # in this case it's "master.txt"
array[$1]=$2      # add column 1 to an array with a value of column 2
next              # go onto the next record

{                 # this could be written as: FNR!=NR
                  # so this means "while we process the second file listed..."
for (i in array)  # means "for every element/key in the array..."
gsub(i, array[i]) # perform a global substitution on each line replacing the key
                  # with it's value if found
}1                # this is shorthand for 'print'
Run Code Online (Sandbox Code Playgroud)

添加单词边界会使匹配更严格:

awk 'FNR==NR { array[$1]=$2; next } { for (i in array) gsub("\\<"i"\\>", array[i]) }1' master.txt file.txt
Run Code Online (Sandbox Code Playgroud)


Tho*_*hor 5

你可以为你sed写一个sed脚本:

映射:

cat << EOF > mappings
1.12.2.4               1
1.12.2.7               12
1.12.2.2               5
1.12.2.4               4
1.12.2.6               67
1.12.2.12              5
EOF
Run Code Online (Sandbox Code Playgroud)

输入文件:

cat << EOF > infile
The Id of the customer is 1.12.2.12. He is from Grg. 
The Name of the machine is ASB
The id is 1.12.2.4. He is from Psg.
EOF
Run Code Online (Sandbox Code Playgroud)

根据映射生成脚本(GNU sed):

sed -r -e 's:([^ ]*) +(.*):s/\\b\1\\b/\2/g:' mappings
Run Code Online (Sandbox Code Playgroud)

输出:

s/\b1.12.2.4\b/1/g
s/\b1.12.2.7\b/12/g
s/\b1.12.2.2\b/5/g
s/\b1.12.2.4\b/4/g
s/\b1.12.2.6\b/67/g
s/\b1.12.2.12\b/5/g
Run Code Online (Sandbox Code Playgroud)

与另一个sed(GNU sed)评估:

sed -r -e 's:([^ ]*) +(.*):s/\\b\1\\b/\2/g:' mappings | sed -f - infile
Run Code Online (Sandbox Code Playgroud)

输出:

The Id of the customer is 5. He is from Grg. 
The Name of the machine is ASB
The id is 1. He is from Psg.
Run Code Online (Sandbox Code Playgroud)

请注意,映射被视为正则表达式,例如,dot(.)可以表示任何字符,并且可能需要在映射文件中或生成sed脚本时转义.