【问题标题】:Why delete using sed is not working?为什么使用 sed 删除不起作用?
【发布时间】:2018-07-27 04:34:23
【问题描述】:

我正在使用 Linux。我有一个 yml 文件,我想使用 sed 删除它:

exposureMachineSshAccess  
  username:
  password:
  whiteList:
    - mLB99
    - mLB10
  machines:
  - machineId:
    username: ''
    password: ''
  - machineId:
    username: ''
    password: ''

我已经创建了这个正则表达式,它看起来不错:

exposureMachineSshAccess:\n([ ].*\n)+

我叫这个:

sed -i '/exposureMachineSshAccess:\n([ ].*\n)+/d'  /home/common_config.yml
sed -i 's/exposureMachineSshAccess:/d/gm' /home/common_config.yml

如果我删除正则表达式,我会更改文件,但反过来就不行了。怎么了?

【问题讨论】:

标签: linux awk sed


【解决方案1】:

您的正则表达式不起作用的原因是sed 一次检查一行。您想删除地址范围内的行,其中起始地址为exposureMachineSshAccess 行,结束地址为password: 行。

sed -i '/exposureMachineSshAccess/,/    password:/d' common_config.yml

这仍然不精确,因为它要求密码行是此 YAML 记录中的最后一行。如果记录之间有空行,请将其用作结束地址。如果您有可靠的缩进,可能会停在与左边距齐平的下一行(但这需要对脚本进行一些重构,以免删除范围末尾的行)。

正确的解决方案是使用正确理解 YAML 的工具。我为这个问题提出了一个副本,它有一些模糊的 Python sn-ps,它可能比口香糖和胶带方法更精确、更健壮,即尝试仅使用正则表达式处理结构化文件格式。

【讨论】:

    【解决方案2】:

    tacsed 的解决方案:如果您不想这样做,它将删除 Input_file 中字符串 password: 的最后一次出现,那么解决方案 2nd 可以帮助您:

    tac Input_file | sed "/    password: ''/,/exposureMachineSshAccess/d" | tac
    

    假设以下是 Input_file:

    cat Input_file
    exposureMachineSshAccess
      username:
      password:
      whiteList:
        - mLB99
        - mLB10
      machines:
      - machineId:
        username: ''
        password: ''
      - machineId:
        username: ''
        password: ''
    singh is king ......
    test1221
    

    那么上面的代码运行后输出如下:

    tac  Input_file | sed "/    password: ''/,/exposureMachineSshAccess/d" | tac
    testtest1221  test
    singh is king ......
    test1221
    

    解决方案二:

    sed  "/exposureMachineSshAccess/,/    password: ''/d"   Input_file
    

    【讨论】:

    • 这将从文件中第一次出现的password: 中删除,不受当前 YAML 记录的限制。
    • @tripleee,对不起,tripleee 先生,我认为这是 OP 需要的,应该删除字符串 OP 粘贴(并尝试放入正则表达式)。如果我做错了什么,请纠正我,然后可以改进它。
    • @DOWN VOTER:请在这里告诉我投反对票的原因??
    • 假设有数百条带有password:的记录,但只有一条以exposureMachineSshAccess开头。
    • @tripleee,是的,我牢记这一点,所以只有我使用tac,如果 OP 可以让我知道 OP 只希望它第一次出现然后可以更改代码。
    【解决方案3】:

    这可能对你有用(GNU sed):

    sed '/^\S/h;G;/\nexposureMachineSshAccess/!P;d' file
    

    这会复制节标题。将节标题附加到每一行并根据节标题匹配打印/删除。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-26
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 2014-11-19
      • 1970-01-01
      • 2020-04-02
      相关资源
      最近更新 更多