Замените поле на значения, указанные в другом файле
У меня есть файл, содержащий карту между словами. Я должен обратиться к этому файлу и заменить эти слова на сопоставленные в некоторых файлах. Например, ниже в файле есть таблица слов, которые отображаются как
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
У меня будет много файлов с этими ключевыми словами (1.12.2. *). Я хочу найти эти ключевые слова и заменить эти слова соответствующим отображением, взятым из этого файла. Как это сделать в оболочке. Предположим, что файл содержит следующие строки:
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.
После выполнения script номера "1.12.2.12" и "1.12.2.4" должны быть заменены на 5 и 4 (см. основной файл). Может ли кто-нибудь помочь мне?
Ответы
Ответ 1
Один из способов: GNU awk
:
awk 'FNR==NR { array[$1]=$2; next } { for (i in array) gsub(i, array[i]) }1' master.txt file.txt
Результаты:
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.
Чтобы сохранить вывод в файл:
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
Объяснение:
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 "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 value if found
}1 # this is shorthand for 'print'
Добавление границ слов делает соответствие более строгим:
awk 'FNR==NR { array[$1]=$2; next } { for (i in array) gsub("\\<"i"\\>", array[i]) }1' master.txt file.txt
Ответ 2
У вас может быть sed
написать sed
script для вас:
Отображения:
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
Входной файл:
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
Создать script на основе сопоставлений (GNU sed):
sed -r -e 's:([^ ]*) +(.*):s/\\b\1\\b/\2/g:' mappings
Вывод:
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
Оцените с помощью другого sed
(GNU sed):
sed -r -e 's:([^ ]*) +(.*):s/\\b\1\\b/\2/g:' mappings | sed -f - infile
Вывод:
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.
Обратите внимание, что сопоставления рассматриваются как регулярные выражения, например. точка (.
) может означать любой символ и может потребоваться экранирование в файле сопоставлений или при генерации sed
script.
Ответ 3
Поскольку вы не предоставили какой-либо пример, я думаю, это то, что вы хотите:
Входной файл
> cat temp
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
файл, который будет вставлен
> cat temp2
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.
Выход
> temp.pl
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
>
Ниже приведен perl script.
#!/usr/bin/perl
use strict;
use warnings;
my %hsh=();
open (MYFILE, 'temp');
open (MYFILE2, 'temp2');
while (<MYFILE>) {
[email protected] = split/\s+/;
$hsh{$arr[0]} = $arr[1];
}
my $flag;
while(<MYFILE2>)
{
$flag=0;
my $line=$_;
foreach my $key (keys %hsh)
{
if($line=~/$key/)
{
$flag=1;
$line=~s/$key/$hsh{$key}/g;
print $line;
}
}
if($flag!=1)
{
print $line;
$flag=0;
}
}
close(MYFILE);
close(MYFILE2);