Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 使用bash将find/replace命令与echo连接起来_Regex_Bash_Shell_Perl_Replace - Fatal编程技术网

Regex 使用bash将find/replace命令与echo连接起来

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

我有一个包含多个before/after值的CSV文件,我正在使用它查找和替换另一个大数据文件(~200MB)中的值

我最初在每个before/after值和sed中使用循环读取来实现查找和替换

问题是它有点慢是可以理解的,所以我想尝试在一行中运行所有的find/replace,以分号分隔,看看只需遍历目标数据文件一次是否会更快

所以我有两个价值观:

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脚本中的perl
one-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对无引号变量引用所做的操作。我建议找出像这样的常见错误。