Однострочный рецепт Perl: Преобразование списков в «разделенные запятыми строки в одинарных кавычках» ИЛИ «несколько строк» ​​на лету - PullRequest
0 голосов
/ 03 февраля 2019

В: Как быстро и удобно конвертировать списки на лету для дальнейшей обработки?

Основное внимание уделяется общему подходу для достижения полностью плавного рабочего процесса (без хлопот обработки файлов, конвейеров)., cut & past и т. д.) для дальнейшей обработки.

Q1) Преобразование списков в разделенные запятыми строки в одинарных кавычках

В основном необходимо для вставки значений в базах данных подобноMySQL, MariaDB, Oracle и т. Д.

Преобразование A B C в 'A','B','C'

Q2: Как преобразовать список идентификаторов в список команд, используя идентификаторы

В основном необходимо повторить одну команду, скажем, с несколькими номерами процессов, чтобы завершить многочисленные сеансы isakmp (VPN) на маршрутизаторе Cisco из-за отсутствия возможностей оболочки (например, for-loop илиxargs) в командной строке IOS (несмотря на то, что это может быть достигнуто с помощью Cisco IOS tclsh ).

Преобразование 23828 11281 22873 3765 1234 в

clear crypto isakmp 23828
clear crypto isakmp 22873
clear crypto isakmp 11281
clear crypto isakmp 22873
clear crypto isakmp  3765
clear crypto isakmp  1234

Добавление восновное внимание об этомВопрос

Я полностью осведомлен о риске атак с использованием SQL-инъекций.Но безопасность здесь не главное, поскольку я знаю, какие данные хранятся в моих списках.Основное внимание уделяется более универсальному подходу для преобразования списков на лету, при этом максимально гибкому .Конечно, некоторые задачи могут быть лучше достигнуты с помощью соответствующего инструмента, такого как sed, awk, tr, cut или любого другого инструмента, который гудит вокруг.К сожалению, каждый раз, выбирая best инструмент для конкретной задачи , вы должны поиграться с синтаксисом, переключателями и узнать, как этот инструмент работает.Это именно то, что я хочу избежать, имея под рукой более общий подход.

Поэтому помните о теме: вызов однострочного Perl простым нажатием клавиши, которую можно легко отрегулировать / отредактировать в оболочке перед ее выполнением.Мой подход - посмотрите ответ сам и этот как побочный узел - выполняет именно это требование.Таким образом, было бы неплохо прочитать мой ответ, прежде чем просто опубликовать решение или предложение на вопрос.; -)

Ответы [ 4 ]

0 голосов
/ 04 февраля 2019

Вы говорите, что вашим первым требованием является "В основном необходимо для вставки значений в базы данных".Решение, которое вы придумали, открыто для атак SQL-инъекций и его следует избегать.

Чтобы избежать этой проблемы, вы всегда должны использовать точки привязки при вставке внешних данных в базу данных.Примерно так:

open my $fh, '<', 'somefile.txt' or die $!;

chomp(my @data = <$fh>);

my $sql = 'INSERT INTO some_table VALUES (';
$sql .= join ',', ('?') x @data;
$sql .= ')';

# Assume you already have a $dbh
my $sth = $dbh->prepare($sql);
$sth->execute(@data);

(Конечно, всегда полезно явным образом перечислять имена столбцов, в которые вы вставляете данные - здесь я опущен для простоты.)

0 голосов
/ 03 февраля 2019

В вопросе говорится, что мы не используем вырезание и вставку и т. Д., Поэтому я предполагаю, что мы берем элементы списка и обрабатываем их внутри скрипта Perl.

Q1 представляет собой очень опасный способ вставки в SQL.Если отдельные элементы списка содержат символы, которые Perl не считает специальными, а SQL считает, то вы открыли базу данных для атаки с использованием инъекций .

Вместо того, чтобы объединять список вPerl, вы должны создать подготовленный оператор для вашего уровня DBI и затем передать элементы списка непосредственно в качестве аргументов.

Хотя есть возможность правильно санировать элементы списка, чтобы избежать неправильной интерпретации при обработкеКак и в SQL, использование метода подготовленных операторов с гораздо меньшей вероятностью приведет к дыре в безопасности.

То же самое относится и к Q2.Несмотря на то, что номера идентификаторов процессов легко проверяются, в общем случае лучше передавать аргументы напрямую, например, используя многопараметрическую форму Perl exec () или system ().

0 голосов
/ 04 февраля 2019

Q1) Есть 2 способа.

$ echo "A B C" | perl -lpe ' s/(\S+)/\x27$1\x27/g ; s/\s+/,/g '
'A','B','C'

$ echo "A B C" | perl -ne ' @x=split(/\s+/); $_="\x27$_\x27" for(@x); print join(",",@x) '
'A','B','C'

Q2)

$ echo "23828 11281 22873 3765 1234" | perl -lane ' print "clear crypto isakmp $_" for(@F) '
clear crypto isakmp 23828
clear crypto isakmp 11281
clear crypto isakmp 22873
clear crypto isakmp 3765
clear crypto isakmp 1234

$
0 голосов
/ 03 февраля 2019

И то, и другое можно быстро и легко сделать с помощью однострочного короткого perl-файла.

A1: создать одну строку (т.е. одну строку) с разделенными запятыми строками в одинарных кавычках

Сначала создайте список, который будет использоваться в следующих (SQL) примерах:

cat > list.txt <<EOF
A
B
C
D
EOF

Или в стиле Perl:

perl -le 'print foreach (A..D)' > list.txt

Создание разделенной запятойсписок со строками из одинарных кавычек:

Чтобы избежать проблем с интерпретацией одинарных кавычек в bash, используйте двузначное шестнадцатеричное значение ASCII \ x27 для одинарных кавычек <<strong>'>.

perl -e 'print join ",", map { chomp; qq(\x27$_\x27) } <>' list.txt     # 'A','B','C','D'

Тот же принцип, только использование восьмеричного значения ASCII \ 047 :

 perl -e 'print join ",", map { chomp; qq(\047$_\047) } <>' list.txt    # 'A','B','C','D'

Для других целей (не SQL), гденеобходимы двойные кавычки:

 perl -e 'print join ",", map { chomp; qq("$_") } <>' list.txt          # "A","B","C","D"

В случае, если #, ; или : необходимы в качестве разделителя, просто замените , в двойных кавычках join ",", на то, чтотребуется.

Например:
join "#",
join ";",
join ":",

Как в большинстве случаев списки принимаютсявырезать и вставлять из другого места.Итак, использование pbpaste на Mac OS X |macos может существенно сократить рабочий процесс.Кстати: любая подсказка для эквивалентной команды Linux будет принята с благодарностью.Чтобы проверить следующий пример, сначала заполните буфер созданным списком: cat list.txt | pbcopy

 pbpaste | perl -e 'print join ",", map { chomp; qq(\x27$_\x27) } <>'

Еще короче;замените содержимое буфера обмена преобразованным списком на лету, используя pbcopy:

 pbpaste | perl -e 'print join ",", map { chomp; qq(\x27$_\x27) } <>' | pbcopy

, чтобы иметь его под рукой при необходимости (например, нажав ctrl + x + c ~ c для преобразования ), просто напишите эту строку в $ HOME / .inputrc

"\C-xc": "pbpaste | perl -e 'print join ",", map { chomp; qq(\x27$_\x27) } <>' | pbcopy"

Активируйте привязку клавиш (см. readline или многие вопросы с тегами , чтобы узнать больше):

 bind -f $HOME/.inputrc     # read/activate settings
 bind -s                    # show key-bindings

Теперь просто нажмите ctrl + x + c для полностью автоматизированного преобразования значений SQL INSERT.

Для полноты изложения некоторые аннотации по поводу цитирования SQL

Выдержка из этого очень хорошего разъяснения о кавычках и обратных галочках : Следует использовать одинарные кавычкидля строковых значений, как в списке VALUES () .Двойные кавычки также поддерживаются MySQL для строковых значений, но одинарные кавычки более широко принимаются другими СУБД, поэтому полезно использовать одинарные кавычки вместо двойных кавычек.

A2: Создать список команд(т.е. много строк) из списка (например, номера процессов)

Этот подход создает, в отличие от A1, несколько строк (повторение команд с идентификаторами процессов).

И снова: Сначала создайте список, который будет использоваться для следующего (Cisco) примера:

perl -le 'print foreach (1000..1010)' | pbcopy

В действительности скопируйте реальные идентификаторы процесса в буфер обмена;после этого преобразуйте простой список чисел в соответствующий список команд:

pbpaste | perl -wle 'while (<>) {chomp; print "clear crypto isakmp $_"}'

Это дает:

clear crypto isakmp 1000
clear crypto isakmp 1001
clear crypto isakmp 1002
clear crypto isakmp 1003
clear crypto isakmp 1004
clear crypto isakmp 1005
clear crypto isakmp 1006
clear crypto isakmp 1007
clear crypto isakmp 1008
clear crypto isakmp 1009
clear crypto isakmp 1010

Чтобы иметь его под рукой, когда это необходимо (например, нажав Ctrl + x + p ~ p для списка процессов ), просто напишите эту строку в $ HOME / .inputrc

"\C-xc": "pbpaste | perl -wle 'while (<>) {chomp; print "clear crypto isakmp $_"}' | pbcopy"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...