Regex 使用bash将find/replace命令与echo连接起来
我有一个包含多个before/after值的CSV文件,我正在使用它查找和替换另一个大数据文件(~200MB)中的值 我最初在每个before/after值和sed中使用循环读取来实现查找和替换 问题是它有点慢是可以理解的,所以我想尝试在一行中运行所有的find/replace,以分号分隔,看看只需遍历目标数据文件一次是否会更快 所以我有两个价值观:Regex 使用bash将find/replace命令与echo连接起来,regex,bash,shell,perl,replace,Regex,Bash,Shell,Perl,Replace,我有一个包含多个before/after值的CSV文件,我正在使用它查找和替换另一个大数据文件(~200MB)中的值 我最初在每个before/after值和sed中使用循环读取来实现查找和替换 问题是它有点慢是可以理解的,所以我想尝试在一行中运行所有的find/replace,以分号分隔,看看只需遍历目标数据文件一次是否会更快 所以我有两个价值观: find="ABC" replace="DEF" 然后我初始化了变量: cmd="" 在循环中,我尝试使用以下命令: cmd="${cmd}s
find="ABC"
replace="DEF"
然后我初始化了变量:
cmd=""
在循环中,我尝试使用以下命令:
cmd="${cmd}s/${find}/${replace}/g;"
想法是将所有内容连接成一个长字符串,如下所示:
"s/FIND1/REP1/g;s/FIND2/REP2/g;s/FIND3/REP3/g; ..." And so on
然后我可以运行命令:
perl -i -p -e ${cmd} TARGET_FILE
问题是我的cmd输出看起来非常奇怪:
echo ${cmd}
/DEF/g;ABC
顺序完全混乱,我甚至尝试将${cmd}设置为类似“test”的字符串,以查看发生了什么,并且输出没有改变。不知怎的,变量顺序颠倒了,前面的“s”没有出现
我尝试改用printf,得到了同样的结果。我尝试过删除分号、更改正斜杠、转义字符以及其他各种方法,但似乎没有任何效果。有人能告诉我这个命令是怎么回事,为什么会出现这种奇怪的行为吗?在单个字符串中执行此操作是不可伸缩的。多次更换也没有效率 这个Perl one liner将带有模式和替换(“before”和“after”值)的csv文件读入哈希
%到。然后,它通过连接所有“before”值来构造regex$pat
。然后读取文件,将“before”替换为“after”,并将结果打印到输出文件中
cat > pats.csv <<EOF
FIND1,REP1
FIND2,REP2
FIND3,REP3
EOF
cat > in.txt <<EOF
foo FIND1,FIND2,FIND1
bar FIND2 bar
FIND3
EOF
perl -lpe '
BEGIN {
%to = map { chomp; split m{,}, $_ }
do { local @ARGV = q{pats.csv}; <> };
$pat = join q{|}, keys %to;
$pat = qr{($pat)};
}
s{$pat}{$to{$1}}gxms;
' in.txt > out.txt
cat out.txt
# Prints this:
foo REP1,REP2,REP1
bar REP2 bar
REP3
cat>pats.csv您没有很好地表达您的问题。哪里是带有find,replace
对的CVS文件示例?其中是包含至少几行数据的数据片段。您是否正在尝试实现包装到shell脚本中的perlone-liner
?或者,如果您想实现为perl脚本,那么很高兴看到您在这方面所做的努力:您已经尝试过的代码。对于测试,您可以使用perl-0777-pe/$find/$replace/g'file_name
,如果您对结果感到满意,可以就地替换perl-0777-e's/$find/$replace/g'-i.bak file_name
。包装perl脚本进入shell的循环不是很有效——您要求perl打开脚本文件,读取它,分析它,运行它,脚本退出,现在循环在循环中一次又一次地重复。看起来您的变量中有回车字符,可能是因为脚本和/或CSV文件是DOS/Windows格式的(请参阅和)。将文件转换为unix格式以避免麻烦。此外,双引号变量引用(例如,perl-i-p-e“${cmd}”目标_文件
,而不是perl-i-p-e${cmd}目标_文件
),以避免shell对无引号变量引用所做的操作。我建议找出像这样的常见错误。