Еще один в awk (ну, два на самом деле). Это для идеального мира:
$ awk 'NR==FNR{a[$1]=[110];next}{sub($NF,a[$NF])}1' source natlog
14 172.18.2.12 445 SMB
50 172.18.24.4 123 Network Time Protocol (NTP)
80 10.2.123.37 22 SSH
68 172.18.1.37 25 SMTP(Insecure)
Объяснено (и немного расширено для несовершенного мира):
$ awk '
NR==FNR { # processing the source file
# gsub(/&/,"\\\\&") # if & chars in the file, uncomment to escape them
a[$1]=[111] # hash to a, port is the key
next
}
{ # process natlog file
sub($NF,a[$NF]) # replace port field with entry from source file
# sub($NF,(a[$NF]?a[$NF]:$NF)) # if gaps in source, use this instead of above
}1' source natlog
Один из возможных выходов (более короткий ip, &
char в источнике и непревзойденный порт 222):
14 1.18.2.12 445 SMB &
50 172.18.24.4 123 Network Time Protocol (NTP)
80 10.2.123.37 222
68 172.18.1.37 25 SMTP(Insecure)
Вы теряете это не в задании, а в эхо. Вы можете видеть это ясно, если вы:
echo "${out}"
Вы увидите похожий эффект со следующим сценарием:
x="Hello,
I
am
a
string
with
newlines"
echo "====="
echo ${x}
echo "====="
echo "${x}"
echo "====="
, который выводит:
=====
Hello, I am a string with newlines
=====
Hello,
I
am
a
string
with
newlines
=====
И, неважно, на ваш вопрос, но я бы все равно хотел упомянуть об этом, я предпочитаю использовать конструкцию $ () вместо обратных кавычек, просто для того, чтобы иметь возможность вкладывать команды. Таким образом, ваша строка сценария становится такой:
out=$(grep apache README)
Теперь это может выглядеть не иначе (и это не так), но делает возможными более сложные команды, такие как:
lines_with_nine=$(grep $(expr 7 + 2) inputfile)
Поместить $ в кавычки:
#!/usr/local/bin/bash
out=`grep apache README`
echo "$out";
Кавычки переменных в bash сохраняют пробелы.
Например:
#!/bin/bash
var1="A B C D"
echo $var1 # A B C D
echo "$var1" # A B C D
, так как символы новой строки являются пробелами, они «удаляются»