如何在BASH中找到并替换文件每行中模式的第一个匹配?

时间:2014-10-29 22:45:09

标签: bash awk sed

我需要在,的文件的每一行上找到并替换1,的第一个外观,例如:

0001,mountain,a big rock
0002,tree,a tall plant
0003,whale,a big fish
0004,lion,a big cat
0005,iPhone,a small computer

输出如下:

00011,mountain,a big rock
00021,tree,a tall plant
00031,whale,a big fish
00041,lion,a big cat
00051,iPhone,a small computer

我所知道的唯一解决方案涉及使用while循环,这需要很长时间才能生成长文件:

while read -r line
do
    sed -i 's/,/1,/' file.csv
done < file.csv

如何找到并替换文件中每行的第一个匹配项?

5 个答案:

答案 0 :(得分:4)

循环是不必要的。只需在没有循环的情况下运行sed命令,它将一次处理整个文件。

sed -i 's/,/1,/' file.csv

答案 1 :(得分:2)

你可以用纯粹的Bash做:

new_lines=()
while IFS= read -r line || [[ $line ]] ; do
    new_lines+=( "${line/,/1,}" )
done <file.csv
printf '%s\n' "${new_lines[@]}" >file.csv

设置IFS并使用'-r'选项'read'以确保正确读取行。

测试'[[$ line]]'以允许'read'在读取未终止的最后一行后返回FALSE。

然而,这个解决方案将整个文件读入内存,而Cygwin的基准测试显示它比纯'sed'解决方案慢100倍。它可能只适用于长达一万行的文件。

如果您正在处理非常大的文件,其他工具可能比“sed”快得多。可能的'perl'解决方案是:

perl -i -ple 's/,/1,/' file.csv

答案 2 :(得分:2)

由于您要编辑该文件,为什么不使用标准编辑器ed

ed -s file < <(printf '%s\n' ',s/,/1,/' 'wq')

,s/,1,/告诉ed在每一行上执行替换s/,/1,/,是整个文件1,$的简写)。然后,w rite和q uit。

如果你不喜欢流程替代基础<(...)(但为什么你不喜欢它?),

printf '%s\n' ',s/,/1,/' 'wq' | ed -s file

答案 3 :(得分:1)

你也可以通过awk这样做,

$ awk '{sub(/,/,"1,")}1' file
00011,mountain,a big rock
00021,tree,a tall plant
00031,whale,a big fish
00041,lion,a big cat
00051,iPhone,a small computer

答案 4 :(得分:1)

nawk -F"," '{$1=$1 1}1' OFS="," file