bash替换特定行上某个位置的字符

时间:2017-01-24 18:32:33

标签: bash

我有一个看起来像这样的文件:

 [                                 
{                                 
     "ncyc" :  28817,         
    "icels" :    128,         
    "jcels" :    128,         
        "t" :   0.185896E-006,
       "dt" :   0.955602E-012,
   "dtcour" :   0.100000E+021,
      "dti" :   0.100000E+021,
      "dtc" :   0.262902E-011,
    "dtvol" :   0.239735E-010,
   "dthall" :   0.100000E+021,
  "dtlaser" :  -0.925596E+062,
    "dtmax" :   0.200000E-009,   
}
]

我想删除此文件的最后一个逗号。它出现在第34行的第14行。如果它是一个文件,我可以手动执行此操作,但我必须为300个文件执行此操作

4 个答案:

答案 0 :(得分:1)

sed是你的朋友:

sed -i.bak '14s/,[[:blank:]]*$//' file ...

这有点脆弱:它假设要删除的行始终是第14行,不一定是结束括号之前的行。

答案 1 :(得分:1)

根据平台sedawk可能会有不同的结果,perl可能更灵活:

perl -i.bak -00pe 's/,(?!.*,)//s' file
# , matches a comma.
# (?!.*,) negative lookahead asserts no comma after matched comma. 
# s is a DOTALL modifier matching newline characters also.

答案 2 :(得分:1)

这是一个简单的单行代码:

ed foo.json <<EOF
?,?s/,\([^,]*\)$/\1/
wq
EOF

该行可以分为地址和命令。

地址为?,?,即与正则表达式,匹配的上一行。

命令为s/re/replacement/,其中正则表达式为,\([^,]*\)$(文字,,零个或多个字符的捕获组,不是,,行尾),替换为\1(第一个捕获的组)。

从技术上讲,它是一个两行编辑脚本wq来保存和退出。

您可以在find的循环中调用它,例如:

find . -name '*.json' | while read name ; do
ed -s $name <<EOF
H
[…ed commands…]
wq
EOF
done

我还添加了ed -s来取消文件大小消息,并H输出详细错误而不是臭名昭着的?

答案 3 :(得分:0)

感谢您的回答。我很容易用Python自己解决这个问题:

  f=open(fjson, 'r')
  data= f.readlines()
  ndx=len(data)
  data[ndx-3]= data[ndx-3].replace(',', '')