重点在于实现完全流畅的工作流程(无需麻烦地处理文件,管道,剪切和过去等)以进行进一步处理的通用方法。
最需要在数据库(如MySQL,MariaDB,Oracle等)中插入值。
将A B C
转换为'A','B','C'
由于缺乏外壳功能(例如,由于缺少外壳功能,因此大多数情况下需要重复使用具有多个进程号的单个命令)以终止Cisco路由器上的多个isakmp会话(VPN) (尽管可以使用Cisco IOS tclsh来实现-OS或Xargs)。
将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单线,在执行之前,可以在shell中轻松地对其进行调整/编辑。我的方法-将我自己的答案和this作为一个副节点-完全满足此要求。 因此,在发布解决方案或建议进行提问之前,最好先阅读我的答案。 ;-)
答案 0 :(得分:0)
两者都可以快速且容易地使用短的perl一行程序完成。
<强>首先创建下述(SQL)的例子中使用的列表:强>
cat > list.txt <<EOF
A
B
C
D
EOF
或者在Perl样式:
perl -le 'print foreach (A..D)' > list.txt
用单引号引起来的逗号分隔列表:
为了避免与bash的单引号解释相抵触,请对单引号<'>使用两位十六进制ASCII值 \ x27 。
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 ":",
在大多数情况下,列表是采取剪切和从其他地方粘贴。因此,在{em> Mac OS X上pbpaste
的使用|的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或许多问题标记readline,进一步):
bind -f $HOME/.inputrc # read/activate settings
bind -s # show key-bindings
现在只需按 ctrl + x + c 即可自动转换您的SQL INSERT值。
:用于完整起见约SQL-引用强>
一些注解Excerpt taken from this very good clarification about quotes and backticks:单引号应用于VALUES()列表中的字符串值。 MySQL也支持字符串值使用双引号,但是单引号已被其他RDBMS广泛接受,因此使用单引号代替双引号是一个好习惯。
与A1相比,此方法建立了多行(具有进程ID的命令重复)。
再次:首先创建一个列表,用于以下(Cisco)示例:
perl -le 'print foreach (1000..1010)' | pbcopy
实际上,将真实的进程ID复制到剪贴板;之后,将简单的数字列表转换为适当的命令列表:
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"
答案 1 :(得分:0)
该问题表明我们没有使用剪切粘贴等功能,因此我假设我们正在使用列表项并在Perl脚本中对其进行处理。
Q1提出了一种非常危险的方式来插入SQL。如果各个列表项恰好包含Perl认为不是特殊字符但SQL却认为特殊字符,则您已将数据库打开为injection attack。
您应该在DBI层中创建一个prepared statement,而不是在Perl中合并列表,然后将列表项直接作为参数传递。
虽然可以正确清理列表中的元素,以避免在被视为SQL时被误解,但是使用预处理语句方法不太可能导致安全漏洞。
第二季度也是如此。尽管可以轻松地检查进程ID号,但通常情况下,最好直接传递参数,例如使用Perl的exec()或system()多参数形式。
答案 2 :(得分:0)
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'
第二季度
$ 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
$
答案 3 :(得分:0)
您说您的第一个要求是“最需要在数据库中插入值”。您提出的解决方案对SQL injection attacks开放,应该避免。
为避免此问题,在将外部数据插入数据库时,应始终使用绑定点。像这样:
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);
(当然,明确列出要向其中插入数据的列的名称始终是一个好习惯-为简单起见,在此省略了。)