Вы можете распространять функции из bash в подоболочки bash:
function greet1 {
echo "moin, $1"
}
typeset -fx greet1
greet2() {
echo "servus, $1"
}
typeset -fx greet2
echo "greet1 bob; greet2 alice" | bash
Выход:
moin, bob
servus, alice
Также см.https://docstore.mik.ua/orelly/unix3/upt/ch29_13.htm
Как указано в комментарии, вот пример выполнения такой замены с помощью sed
. Вы использовали тег /linux, поэтому безопасно использовать GNU sed
с его флагом e
для команды s
:
sed -E 'h;s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e;T
G;s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/' logfile
Пояснение:
h
сохраняет строку в резервной области, чтобы мы могли восстановить ее после ошибки в строке (-; s/.*clientMac":\s"([A-Z0-9]{12}).*/echo secretKey\1|md5sum/e
соответствует всей строке, помещая фактический MAC в ()
для повторного использования при замене. Замена формирует команду для выполнения:echo
с MCA вместе с «солью» и передает ее в md5sum
. Флаг e
заставляет sed
выполнить это в оболочке и снова поместить результат в буфер T
переходит в конец скрипта, если замена не производилась. Это для печати строк без немодифицированного MAC. Следующие строки выполняются только в том случае, если была произведена замена G
добавляет исходную строку из буфера удержания, так что теперь у нас есть вывод md5sum
, новая строка и исходная строка в буфере s/(.*)\s*-\n(.*clientMac":\s")[A-Z0-9]{12}(.*)/\2\1\3/
фиксирует MD5 в первой паре ()
, строку перед MAC во второй и остальную часть строки после MAC в третьей, таким образом, \2\1\3
заменяет MAC на MD5 Следующий сценарий perl
использует модульDigest::MD5
илиDigest::SHA
для преобразования MAC-адреса в хэш с использованием секретной соли. См. справочные страницы модулей для получения более подробной информации о них. Стоит отметить, что у Digest ::SHA есть еще несколько алгоритмов на выбор.
Код написан так, чтобы упростить выбор другого алгоритма хеширования. -Раскомментируйте один и закомментируйте остальные, чтобы выбрать наиболее подходящий. Кстати, вывод версий функций _base64
немного короче, чем у функций _hex
, но больше похож на шум строки -.
Я упростил предоставленное вами регулярное выражение (и не вижу необходимости смотреть -за ). Возможно, вам придется немного изменить это, чтобы работать с вашими входными данными.... вы не предоставили никакого образца, поэтому я просто догадался.
#!/usr/bin/perl
# choose one of the following digest modules:
use Digest::MD5 qw(md5_hex md5_base64);
#use Digest::SHA qw(sha256_hex sha256_base64);
use strict;
my $salt='secret salt phrase';
# store seen MAC addresses in a hash so we only have to calculate the digest
# for them once. This speed optimisation is only useful if the input file
# is large AND any given MAC address may be seen many times.
my %macs=();
while(<>) {
if (m/clientMac:\s*([A-Z0-9]{12})/i) {
my $mac = $1;
if (!defined($macs{$mac})) {
# choose one of the following digest conversions:
#my $uuid = sha256_hex($mac. $salt);
#my $uuid = sha256_base64($mac. $salt);
my $uuid = md5_hex($mac. $salt);
#my $uuid = md5_base64($mac. $salt);
$macs{$mac} = $uuid;
};
s/(clientMac:\s*)$mac/$1$macs{$mac}/gio;
};
print;
};
В качестве альтернативного подхода я иногда использовал простые номера строк в качестве запутывающего значения. Это делает вывод более компактным и более читабельным.
Кроме того, awk
– хороший инструмент, когда нужно выполнять "умные" операции с текстовым файлом, имеющим более читаемый язык, чем sed
. «Умная» операция, которую необходимо выполнить в этом случае, состоит в том, чтобы избежать повторного -выполнения алгоритма запутывания, когда какой-либо один MAC-адрес встречается более одного раза. Это может значительно ускорить работу, если у вас есть тысячи строк, относящихся к небольшому количеству MAC-адресов.
На практике рассмотрим следующий сценарий, который также обрабатывает возможные множественные MAC-адреса, встречающиеся в любой строке, идентифицируя и заменяя каждое вхождение, а затем печатает таблицу сопоставления в конце:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v table='sort -k 1,1n | column -t' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
if (!($i in cache))
cache[$i]=NR "." i
$i = "MAC:" cache[$i]
}
}
1
END {
print "---Table: "FILENAME"\nnum MAC" | table
for (mac in cache)
print cache[mac], mac | table
}
' file.log
Таблицу в конце можно легко отделить от основного вывода дополнительным шагом редактирования или просто заставив командную строку в аргументе -v table=
перенаправить вывод в файл, как в -v table='sort -k 1,1n | column -t > table'
. Его также можно полностью удалить, просто удалив весь блок END{ … }
.
Как вариант, использование реального механизма шифрования для вычисления значений запутывания и, следовательно, отсутствие таблицы сопоставления в конце:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='openssl enc -aes-256-cbc -a -pass file:mypassfile' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
addr = cache[$i]
if (addr == "") {
"echo '\''" $i "'\'' | " crypter | getline addr
cache[$i] = addr
}
$i = "MAC:" addr
}
}
1
' file.log
Здесь я использовал openssl
в качестве механизма шифрования, выбрав его aes-256-cbc
шифр (с выходом в кодировке base64 -, чтобы он был текстовым -дружественным ), и заставил его читать секрет шифрования. из файла с именем mypassfile
.
Строки, зашифрованные с помощью симметричного шифра (типа aes-256-cbc
), можно расшифровать, зная секрет, используемый (содержимое mypassfile
, которое вы хотите сохранить для себя ), поэтому их можно обратить. Кроме того, поскольку openssl
по умолчанию использует случайную соль, каждый запуск выдает разные значения для одного и того же ввода. Неиспользование параметра соли (-nosalt
)приведет к тому, что openssl
выдаст одно и то же значение для каждого запуска,поэтому менее безопасный, но, с другой стороны, будет создавать более короткие тексты, все еще будучи зашифрованными.
Тот же сценарий awk
будет работать для других внешних команд вместо openssl
, просто заменив команду в аргументе -v crypter=
на awk
, если выбранная вами внешняя команда может принимать ввод со стандартного ввода и вывод на стандартный вывод.
Строки, хешированные с помощью таких алгоритмов, как MD5 или SHA, являются односторонними -только (, т. е. они не могут быть реверсированы )и всегда дают одно и то же значение для одних и тех же входных данных, поэтому вы захотите «посолить» их, чтобы вычисленные значения, полученные на выходе, нельзя было просто искать по всем возможным MAC-адресам. Вы можете добавить случайную «соль», как в следующем слегка измененном скрипте:
awk -v pat='clientMac"\\s*"[[:xdigit:]]{12}' -v crypter='sha256sum' -- '
$0 ~ pat {
for (i=1; i <= NF; i++)
if (match($i, pat)) {
addr = cache[$i]
if (addr == "") {
"(dd if=/dev/random bs=16 count=1 2>/dev/null; echo '\''" $i "'\'') | " crypter | getline addr
cache[$i] = addr
}
$i = "MAC:" addr
}
}
1
' file.log
Этот последний сценарий использует 16-байтовое -длинное (псевдослучайное -)значение в качестве «соли», таким образом создавая разные хэш-значения при каждом прогоне одних и тех же данных.