Bash 使用.csv文件作为sed函数的数据池

Bash 使用.csv文件作为sed函数的数据池,bash,perl,csv,sed,Bash,Perl,Csv,Sed,我有大量的文本,我想使用sed进行大规模替换,使用.csv文件作为sed引用的数据池。例如,如果我想创建一个.csv文件,它看起来像: bird,snake tree,bush river,stream 然后我想使用sed搜索文本中的第1列字符串,并替换为第2列的值。这是最好用一个调用sed的bash脚本来完成的,还是使用Perl脚本会更成功 最好让一个sed脚本将映射文件转换为第二个sed脚本,然后应用于要转换的数据。既然你说了bash,我就假设你有空。如果没有,则升级bash或使用临时文件

我有大量的文本,我想使用sed进行大规模替换,使用.csv文件作为sed引用的数据池。例如,如果我想创建一个.csv文件,它看起来像:

bird,snake
tree,bush
river,stream

然后我想使用sed搜索文本中的第1列字符串,并替换为第2列的值。这是最好用一个调用sed的bash脚本来完成的,还是使用Perl脚本会更成功

最好让一个
sed
脚本将映射文件转换为第二个
sed
脚本,然后应用于要转换的数据。既然你说了
bash
,我就假设你有空。如果没有,则升级
bash
或使用临时文件

sed -i .bak -f <(sed 's%^ *\([^ ,]\{1,\}\), *\([^ ]\{1,\}\) *$%s/\1/\2/g%' \
                      control-file) \
    datefile-1 datafile-2 ...
代码可以更简单:

sed -i .bak -f <(sed 's%\([^,]*\),\(.*\)%s/\1/\2/g%' control-file) \
    datefile-1 datafile-2 ...

sed-i.bak-f使用Perl。将CSV文件读入散列,从散列键构建正则表达式,并使用散列对文本进行全局子替换以进行翻译

看起来像这样

use strict;
use warnings;
use 5.010;
use autodie;

my $str = <<'__END_TEXT__';
The ripple-necked bird sang melodies by the curling river while
the hooded tiger glowered in the tree beneath her, just out of reach.
__END_TEXT__

open my $fh, '<', 'words.csv';
my %patterns = map {
   chomp;
   split /,/, $_, 2;
} <$fh>;

my $re = join '|', sort { length $b <=> length $a } keys %patterns;

$str =~ s/\b($re)\b/$patterns{$1}/g;

say $str;

您是否参加并阅读了帮助?这是的副本,您应该可以在其中找到答案。我没有参加本教程,但我会在我有能力时阅读。@martin该链接问题不是副本。它特别指通过第二个csv文件中包含的信息翻译csv文件中的一个字段。这里翻译的文本不是孤立于特定字段的,因此这些解决方案不适用。如果我想用单个字母执行此任务,该怎么办?例如,将字母a转换为“oo”,将字母e转换为“i”,这样snake->snooki?如果要在单词中查找字符串(任意长度),则需要从正则表达式中删除
\b
锚定。它们匹配单词边界,因此防止模式匹配不完整的单词。观察:问题的原始版本有一个更复杂的CSV文件,包含多个前导空格、一个单词、一个逗号、一个空格以及可能的尾随空格。这个问题后来被编辑(由OP以外的人)删去了逗号后面的空白和空白,从而改变了答案的复杂性。如图所示,使用
sed
可以解决该问题;使用Perl也可以解决这个问题(因为Perl的一个预期用途是充当
sed
-杀手-因此使用Perl分发
s2p
命令-但是杀戮并没有100%成功)。
use strict;
use warnings;
use 5.010;
use autodie;

my $str = <<'__END_TEXT__';
The ripple-necked bird sang melodies by the curling river while
the hooded tiger glowered in the tree beneath her, just out of reach.
__END_TEXT__

open my $fh, '<', 'words.csv';
my %patterns = map {
   chomp;
   split /,/, $_, 2;
} <$fh>;

my $re = join '|', sort { length $b <=> length $a } keys %patterns;

$str =~ s/\b($re)\b/$patterns{$1}/g;

say $str;
The ripple-necked snake sang melodies by the curling stream while
the hooded tiger glowered in the bush beneath her, just out of reach.