Perl的一个班轮配方:转换列表到“多行”“用单引号逗号分隔的字符串” OR上飞

问题描述 投票:-1回答:4

Q: How to convert lists in a swift and convenient way on the fly for further processing?

重点是普遍的做法,实现了全流程流利(无处理文件,管道的麻烦,切断与过去等)进行进一步的处理。

Q1) Convert lists into comma-separated strings in single quotes

大多需要像MySQL,MariaDB的,甲骨文等数据库中插入值。

转换成A B C 'A','B','C'

Q2: How to convert list of ids into a list of commands using the ids

最需要重复使用一个命令,可以说,多进程编号以终止思科路由器上众多的ISAKMP会话(VPN)由于缺乏壳功能(如for循环或xargs的)的IOS命令行(尽管它可以被使用Cisco IOS tclsh achived)。

转换成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,任何工具寸头或周围实现。不幸的是,每次选择适合你不得不反复折腾的语法,开关和如何抛开工具开展工作的具体任务的最佳工具。这正是我想避免具有手更通用的方法的麻烦。

只需按执行前在shell编辑可以很容易地调整击键/调用一个Perl的一行:因此,牢记的话题。我的做法 - 看到自己的答案,this作为侧节点 - 正好满足了这一要求。因此,它可能只是发布的解决方案或建议质疑之前阅读我的回答是一个好主意。 ;-)

perl
4个回答
0
投票

两者都可以快速,方便地使用短Perl的一个班轮完成。

A1:构建一个字符串(即一个单个线。)与在单引号逗号分隔的字符串

首先创建一个列表如下(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 ":",

在大多数情况下,列表是从别的地方采取剪切和粘贴。因此,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-报价

Excerpt taken from this very good clarification about quotes and backticks:单引号,应在值用于字符串值,像()列表。双引号是由MySQL的字符串值,以及支持,但单引号由其他RDBMS更广泛地接受,所以它是使用单引号代替双引号的好习惯。

A2:创建命令列表从列表中(即多行。)(例如进程号。)

这种方法建立 - 在对比A1 - 多行(命令与进程ID的重复)。

再次:首先创建一个列表将被用于下面的(思科)例如:

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"

0
投票

我们没有使用剪切和粘贴等问题的状态,所以我认为我们正在采取的列表项,并处理它们的Perl脚本里面。

Q1假定一个非常危险的方式插入到SQL。如果单独列表项正好包含Perl不考虑特殊字符,但SQL的话,那么你有你的数据库打开了一个injection attack

而不是在Perl结合列表中,您应该创建一个prepared statement为您的DBI层,然后直接通过列表项作为参数。

虽然能够正确消毒列表的元素,以避免误解时为SQL处理,用事先准备好的声明的做法是不太可能导致安全漏洞。

同样是Q2的真实。虽然进程ID号能够容易地确认,在一般情况下,最好是直接传递参数,例如使用EXEC的Perl的多参数形式()或系统()。


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'

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
投票

你说你的第一个要求是“最需要在数据库中插入值”。你想出了解决的办法是开放的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);

(当然,它总是很好的做法,明确列出,你将数据插入到列的名字 - 我省略了,这里为简便起见)

© www.soinside.com 2019 - 2024. All rights reserved.