Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.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 从列表(或其他文件)中查找并替换匹配的多个参数_Regex_Shell_Sed - Fatal编程技术网

Regex 从列表(或其他文件)中查找并替换匹配的多个参数

Regex 从列表(或其他文件)中查找并替换匹配的多个参数,regex,shell,sed,Regex,Shell,Sed,我写了一个简单的shell脚本,它可以工作,但效率非常低。在较大的文件上运行时间太长。我正在寻找一个更快的解决方案 示例输入文件: data.csv: 1,data,data 3,data,data 4,data,data 9,data,data ... 3 9 16 17 ... matches.txt: 1,data,data 3,data,data 4,data,data 9,data,data ... 3 9 16 17 ... 我编写的脚本遍历matches.txt中的每个项目

我写了一个简单的shell脚本,它可以工作,但效率非常低。在较大的文件上运行时间太长。我正在寻找一个更快的解决方案

示例输入文件:

data.csv

1,data,data
3,data,data
4,data,data
9,data,data
...
3
9
16
17
...
matches.txt

1,data,data
3,data,data
4,data,data
9,data,data
...
3
9
16
17
...
我编写的脚本遍历
matches.txt
中的每个项目。它使用
sed
匹配csv文件中的行的开头,并通过在
**
前面加上前缀将它们注释掉

#!/bin/bash

IFS=$'\r\n' GLOBIGNORE='*' :; XYZ=$(<matches.txt)
for id in ${XYZ[@]}
do
  sed -i '' "${id}s/^**//" data.csv
done
#/bin/bash

IFS=$”\r\n“GLOBIGNORE='*':;XYZ=$(而不是在循环中调用
sed
,您可以使用以下awk:

awk -F ',' 'FNR==NR{a[$1]++; next} $1 in a{$0 = "**" $0} 1' matches.txt data.csv
1,data,data
**3,data,data
4,data,data
**9,data,data
要保存来自
awk
的输出:

awk -F ',' 'FNR==NR{a[$1]++; next} $1 in a{$0 = "**" $0} 1' matches.txt data.csv > _tmp
mv _tmp data.csv
说明:

  • -F','
    -使用字段分隔符作为逗号
  • FNR==NR
    -对第一个文件执行此块
  • {a[$1]+;next}
    -从第一个文件创建一个键为
    $1
    的数组,并移动到下一行
  • a{$0=“**”$0}
    中的$1-对于第二个文件,如果第一个字段位于数组
    a
    中,则在当前行中预加
    **
  • 1
    -默认awk操作(打印行)

Wow!好的,这样可以更快地定位行,但是,我需要修改原始文件。我正在使用的命令进行就地修订。
awk
是否有类似的内容?您能解释一下该命令吗?我在回答中添加了详细信息,还有一种保存输出的方法。如果您使用的是
gnu awk>4.1.0
,那么您可以使用:
awk-i in place-F','FNR==NR{a[$1]+;next}$1在{print“**”$0}'matches.txt data.csv
操作系统X上的
-i
选项不适用于
awk
。阅读手册后,我不知道是否可以进行就地修改。在OSX上它不可用,这就是我在评论中提到gnu awk版本的原因。不过,我正在通过
家用brew
在我的OSX上使用它。您可以只使用临时文件way以将更改迁移回原始文件。