如何使用bash替换csv文件中特定位置的字符串

时间:2018-11-03 03:15:53

标签: bash awk sed cut

我有几个.csv文件,每个csv文件都有看起来像这样的行。

export default class App extends React.Component {
     render() {
          console.disableYellowBox = true;
          return (<View></View>);
     }
}

我正在阅读每个csv文件的每一行,然后尝试以“ ZZ”替换以AA开头的每一行的第4个位置

预期产量

AA,1,CC,1,EE
AA,FF,6,7,8,9
BB,6,7,8,99,AA

但是变量“ y”确实分别包含第4个变量“ 1”和“ 7”,但是当我使用sed命令时,它用“ ZZ”代替了第一次出现的“ 1”。

我如何修改代码以仅替换每行的第4个位置,而不管其持有什么值?

我的代码如下

$ file =“包含所有csv文件列表的文件名”

AA,1,CC,ZZ,EE
EE,FF,6,ZZ,8,9
BB,6,7,8,99,AA

4 个答案:

答案 0 :(得分:2)

使用sed,您还可以将以"ZZ"开头的行的逗号分隔值文件的第4个字段更改为"AA"

sed -i '/^AA/s/[^,][^,]*/ZZ/4' file

说明

  • sed -i调用sed到位编辑文件;
  • 一般形式/find/s/match/replace/occurrence;哪里
    • find/^AA/行,以"AA"开头;
    • match [^,][^,]*一个字符而不是逗号,后跟任意多个非逗号;
    • replace /ZZ/4match一起出现的"ZZ"的第四次出现。

请注意,在这种情况下,awksed都提供了很好的解决方案,因此请查看@perreal@RavinderSingh13的答案

示例输入文件

$ cat file
AA,1,CC,1,EE
AA,FF,6,7,8,9
BB,6,7,8,99,AA

使用/输出示例

注意: -i以下未使用,因此更改仅输出到stdout

$ sed '/^AA/s/[^,][^,]*/ZZ/4' file
AA,1,CC,ZZ,EE
AA,FF,6,ZZ,8,9
BB,6,7,8,99,AA

答案 1 :(得分:2)

要稳健地做到这一点,就是:

$ awk 'BEGIN{FS=OFS=","} $1=="AA"{$4="ZZ"} 1' csv
AA,1,CC,ZZ,EE
AA,FF,6,ZZ,8,9
BB,6,7,8,99,AA

请注意,以上代码正在进行文字字符串比较和文字字符串替换,因此与到目前为止发布的其他解决方案不同,如果目标字符串(在此示例中为AA)包含正则表达式元字符(如{ {1}}或.,也不能是*之类的另一个字符串的一部分,替换字符串(在本例中为AAX)是否包含诸如ZZ之类的反向引用或&

如果要一次映射多个字符串:

\1

就像GNU sed具有$ awk 'BEGIN{FS=OFS=","; m["AA"]="ZZ"; m["BB"]="FOO"} $1 in m{$4=m[$1]} 1' csv AA,1,CC,ZZ,EE AA,FF,6,ZZ,8,9 BB,6,7,FOO,99,AA 进行“就地”编辑一样,GNU awk也具有-i,因此您可以放弃shell循环而只需执行以下操作:

-i inplace

,它将在一次调用awk的过程中对awk -i inplace ' BEGIN { FS=OFS="," } (NR==FNR) { ARGV[ARGC++]=$0 } (NR!=FNR) && ($1=="AA") { $4="ZZ" } { print } ' file 中命名的所有文件进行操作。在最后一种情况下,“文件”是您的文件,其中包含其他CSV文件名的列表。

答案 2 :(得分:1)

EDIT1: :由于OP更改了要求,因此请立即添加以下内容。

awk 'BEGIN{FS=OFS=","} /^AA/||/^BB/{$4="ZZ"} /^CC/||/^DD/{$5="NEW_VALUE"} 1'  Input_file > temp_file && mv temp_file Input_file

请您尝试以下。

awk -F, '/^AA/{$4="ZZ"} 1' OFS=,  Input_file > temp_file && mv temp_file Input_file

OR

awk 'BEGIN{FS=OFS=","} /^AA/{$4="ZZ"} 1'  Input_file > temp_file && mv temp_file Input_file

说明: 现在也向上述代码添加了说明。

awk '
BEGIN{              ##Starting BEGIN section of awk which will be executed before reading Input_file.
  FS=OFS=","        ##Setting field separator and output field separator as comma here for all lines of Input_file.
}                   ##Closing block for BEGIN section of this program.
/^AA/{              ##Checking condition if a line starts from string AA then do following.
  $4="ZZ"           ##Setting 4th field as ZZ string as per OP.
}                   ##Closing this condition block here.
1                   ##By mentioning 1 we are asking awk to print edited or non-edited line of Input_file.
'  Input_file       ##Mentioning Input_file name here.

答案 3 :(得分:1)

使用sed

sed -i 's/\(^AA,[^,]*,[^,]*,\)[^,]*/\1ZZ/' input_file