Вопрос или проблема
У меня есть URL вроде этого: bbc:osdb://://user=&pass=abc%sec=true
Я хочу извлечь , , ,
Пример:
bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true
Должно вернуть:
293.23.234.55:1234:john:pass123
grep
или egrep
или sed
или awk
Этот вариант:
grep -Eo '([0-9]+.[0-9]+.[0-9]+.[0-9]+)|[0-9]{4}'
даёт мне первые два, и на двух разных строках…
293.23.234.55
1234
Самый простой подход — с помощью sed
:
echo 'bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc&sec=true' | sed 's#.*://\([0-9\.]\{7,15\}\):\([0-9]\+\)/.*user=\([^&]\+\)&pass=\([^&]\+\).*#\1:\2:\3:\4#'
Обратите внимание, что я исправил то, что, по моему предположению, является опечаткой в оригинальном URL.
Решение с помощью Awk:
{
for (i=1; i <= NF; i++) {
if ($i ~ /[0-9\.]{7,15}/) {
host = $i;
} else if ($i ~ /user=/) {
split($i, params, "&");
for (n in params) {
if (params[n] ~ /user=/) {
user = substr(params[n], 6, 100);
} else if (params[n] ~ /pass=/) {
password = substr(params[n], 6, 100);
}
}
}
}
print host ":" user ":" password;
}
Запустите это, примерно так
cat file.log | awk -F"https://stackoverflow.com/" -f script.awk
Без преимуществ Минимального Полного Воспроизводимого Примера невозможно охватить вашу точную ситуацию, но можно ответить на вопрос о том, как разобрать 293.23.234.55:1234:john:pass123abc
из bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true
. (вы не предоставили правило, чтобы объяснить удаление "abc"
с конца пароля)
Существует много способов сделать это. Самый простой с одной командой — использовать awk
с разделителем полей "https://stackoverflow.com/"
, чтобы разделить части URL, а затем использовать функции split()
и sub()
в awk
, чтобы разобрать информацию. (вы также можете использовать функции match()
и substr()
)
Основная команда awk
для этого:
awk -F/ -v OFS=: '{
split ($NF, arr, "&")
sub (/^.*=/, "", arr[1])
split (arr[2], pwarr, "%")
sub (/^.*=/, "", pwarr[1])
print $3, arr[1], pwarr[1]
}'
Где:
awk -F/ -v OFS=:
вызываетawk
с разделителем полейFS
"https://stackoverflow.com/"
и разделителем полей выводаOFS
':'
,'{
начинает определение правилаawk
,split($NF,arr,"&")
разделяет последнее поле ($NF
) наarr
по"&"
,sub(/^.*=/,"",arr[1])
удаляетuser=
изjohn
split (arr[2], pwarr, "%")
разделяетpass=pass123abc%sec=true
на"%"
наpwarr
,sub(/^.*=/,"",pwarr[1])
удаляетpass=
изpass123abc
print $3,arr[1],pwarr[1]
выводит результат, и}
завершает правило.
Пример/Вывод
$ echo "bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true" |
> awk -F/ -v OFS=: '{
> split ($NF, arr, "&")
> sub (/^.*=/, "", arr[1])
> split (arr[2], pwarr, "%")
> sub (/^.*=/, "", pwarr[1])
> print $3, arr[1], pwarr[1]
> }'
293.23.234.55:1234:john:pass123abc
ПРИМЕЧАНИЕ если вы намеревались удалить "abc"
с конца пароля, сообщите мне. Не было разделителей, которые бы оправдали обрезку последних 3-символов из пароля (кроме как просто случайно обрезать 3-символа с помощью substr()
или sub()
— это не имело смысла). Так что полный пароль остался нетронутым.
Ответ или решение
Извлечение нескольких частей из URL с помощью командной оболочки является распространенной задачей для системных администраторов и разработчиков. В данной статье мы рассмотрим, как это сделать с использованием утилит sed
, awk
или grep
. Задача состоит в том, чтобы извлечь IP-адрес, порт, имя пользователя и пароль из следующего URL:
bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true
Пример желаемого вывода
Результатом должно быть следующее:
293.23.234.55:1234:john:pass123
Решение с помощью sed
Использование sed
для этой задачи может выглядеть следующим образом:
echo 'bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true' |
sed 's#.*://\([0-9]\{7,15\}\):\([0-9]\+\)/.*user=\([^&]*\)&pass=\([^&]*\).*#\1:\2:\3:\4#'
Давайте разберём это выражение:
s#...#...#
: Используется синтаксис замены..*://
– игнорирует все символы до://
.\([0-9]\{7,15\}\)
– извлекает IP-адрес (от 7 до 15 цифр).\([0-9]\+\)
– извлекает порт (одна или более цифр).user=\([^&]*\)
– извлекает имя пользователя, прекращая на первом символе&
.pass=\([^&]*\)
– извлекает пароль, также до первого символа&
.#\1:\2:\3:\4#
– форматирует вывод.
Решение с помощью awk
Вот как решить эту задачу с помощью awk
:
echo 'bbc:osdb://293.23.234.55:1234/bbc-dt-af/user=john&pass=pass123abc%sec=true' |
awk -F/ -v OFS=: '{
split($NF, arr, "&")
sub(/^.*=/, "", arr[1])
split(arr[2], pwarr, "%")
sub(/^.*=/, "", pwarr[1])
print $3, arr[1], pwarr[1]
}'
Объяснение данного подхода:
-F/
устанавливает символ/
как разделитель полей.-v OFS=:
устанавливает символ:
как разделитель вывода.split($NF, arr, "&")
разбивает последнее поле на массивarr
по символу&
.sub(/^.*=/, "", arr[1])
удаляетuser=
из строки, оставляя только имя пользователя.split(arr[2], pwarr, "%")
разбивает строку с паролем по символу%
.sub(/^.*=/, "", pwarr[1])
удаляетpass=
и выводит IP, порт, имя пользователя и пароль.
Использование grep
Использовать grep
можно для извлечения только IP-адреса и порта, однако он не так удобен для извлечения всех необходимых полей в одном результате, как это делают awk
и sed
.
В общем случае grep
можно использовать для предварительного фильтра, чтобы убедиться, что строка содержит нужные данные, а затем передать результат в awk
или sed
.
Заключение
Извлечение информации из структурированных строк, таких как URL, — это очень распространенная задача, и для её решения существует множество подходов. Используемые инструменты, такие как sed
и awk
, предоставляют мощные возможности для обработки текстов и вентильной фильтрации данных. Выбор подхода зависит от конкретных нужд и предпочтений в команде.
Обратите внимание, что данное решение позволяет извлекать данные в необходимом формате, однако, если в вашем случае требуются специфические условия, например, удаление определенных символов из пароля, это обязательно должно быть учтено в регулярных выражениях или подпрограммах.
Если у вас остались вопросы или потребуется дополнительная информация, пожалуйста, дайте знать!