如何检查(和删除)最后一行(包含字符串的最后一次出现)是否有逗号作为最后一个字符?

时间:2016-01-19 15:46:59

标签: linux bash shell awk sed

我一直在网上看,但没有结果。

我正在尝试构建一个包生成器(在shell / bash中),并且相应的包包含(一个或多个)json文件。浏览json文件时,如果用户想要删除其中一个步骤,我必须首先考虑如果要删除的步骤是最后一步。如果是这样,最后一步的前一个将包含一个逗号,但json格式不允许这样做。

{
  "operation_machinetype": "Ford",
  "operation_steps": [
    "steps/Step_1/01_paint_the_car.json",
    "steps/Step_2/01_drive_the_car.json",
    "steps/Step_2/02_park_the_car.json"
  ]
}

示例,如果我删除'"步骤/步骤2 / 02_park_the_car.json"',那么'"步骤/步骤2 / 01_drive_the_car.json" '将是最后一步,但逗号将导致错误。

提前感谢大家。

5 个答案:

答案 0 :(得分:3)

$ cat tst.awk
index($0,tgt) {
    if (!/,[[:space:]]*$/) {
        sub(/,[[:space:]]*$/,"",prev)
    }
    next
}
NR>1 { print prev }
{ prev = $0 }
END { print prev }

$ awk -v tgt='"steps/Step_2/02_park_the_car.json"' -f tst.awk file
{
  "operation_machinetype": "Ford",
  "operation_steps": [
    "steps/Step_1/01_paint_the_car.json",
    "steps/Step_2/01_drive_the_car.json"
  ]
}

$ awk -v tgt='"steps/Step_2/01_drive_the_car.json"' -f tst.awk file
{
  "operation_machinetype": "Ford",
  "operation_steps": [
    "steps/Step_1/01_paint_the_car.json",
    "steps/Step_2/02_park_the_car.json"
  ]

答案 1 :(得分:1)

您可以使用多行正则表达式在结束括号前找到最后一个逗号,例如:

/,\s*]/g

请参阅refiddle

上的示例

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed 'N;s#,\s*\n\s*"steps/Step_2/02_park_the_car\.json"##;P;D' file

一次读取两行,如果找到匹配则删除所需的字符串。然后打印然后删除第一行,然后追加下一行。

N.B。如果模式空间为空,则读取另一行,然后追加下一行。

答案 3 :(得分:1)

我知道该类别是bash,但你应该使用一般具有JSON意识​​的东西,而不仅仅是编辑像它基于行的文件。然后你不必担心正确的json编码,但可以专注于操纵数据。我倾向于使用Python,因为内置的json支持和相对无处不在(因为这在Python中非常简单)。也许就像这个简单的脚本(其中一半以上是错误检查冗长):

#!/bin/env python
import json
import sys

if( len(sys.argv)-1 != 2 ):
  sys.stdout.write('Usage: ' + sys.argv[0] + ' pattern file\n')
  sys.exit(1)

patt = sys.argv[1]
filename = sys.argv[2]

with open(filename, 'r') as data_file:
  data = json.load(data_file)

try:
  data["operation_steps"].remove(patt)
except ValueError:
  sys.stdout.write( 'Pattern "' + patt + '" not found in '
                    + filename + '; leaving file unchanged\n' )
  sys.exit(2)

sys.stdout.write( 'updating ' + filename + '\n' )
with open(filename, 'w') as data_file:
  json.dump(data, data_file, ensure_ascii=False, indent=2)

如果你采用"缩进= 2"在json.dump调用之后,它也会压缩json - 这可能会减少包中浪费的空间。 :)

有几个命令行json操纵器,我一直在为ksh93写一个基于C的可加载模块,但实际上我' 实际上是这样的如果我今天要这样做,就解决问题。

答案 4 :(得分:0)

您可以考虑使用YAML:

---
  operation_machinetype: "Ford"
  operation_steps: 
    - "steps/Step_1/01_paint_the_car.json"
    - "steps/Step_2/01_drive_the_car.json"
    - "steps/Step_2/02_park_the_car.json"