加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Bash脚本:更新属性文件

发布时间:2020-12-16 01:49:39 所属栏目:安全 来源:网络整理
导读:propertyOne=1propertyTwo=a/bpropertyThree=three 如何将属性文件的内容更改为以下模式? propertyOne将在原始值之前添加一个字符串 propertyTwo将在中间添加一个字符串 propertyThree将在末尾添加一个字符串 propertyOne=apple/1propertyTwo=a/and/bproper
propertyOne=1
propertyTwo=a/b
propertyThree=three

如何将属性文件的内容更改为以下模式?

> propertyOne将在原始值之前添加一个字符串
> propertyTwo将在中间添加一个字符串
> propertyThree将在末尾添加一个字符串

propertyOne=apple/1
propertyTwo=a/and/b
propertyThree=three/end

我尝试使用sed -i -e,但是只有在我对每行的更改进行硬编码时我才会成功;任何改进代码的建议?

sed -i -e '/propertyTwo=/ s=.*/=one/2/two' path/to/file

解决方法

在这种情况下,纯Bash解决方案提供了灵活性和稳健性(但下面将进一步了解更快的awk解决方案).

虽然逐行读取文件的Bash解决方案通常很慢,但这可能不会成为属性文件的问题,而属性文件往往很小.

#!/usr/bin/env bash

while IFS='=' read -r prop val; do
  case $prop in
    propertyOne)
      val="apple/$val"
      ;;
    propertyTwo)
      val="${val////and/}"
      ;;
    propertyThree)
      val="$val/end"
      ;;
  esac
  printf '%sn' "$prop=$val"
done < file > file.tmp && mv file.tmp file

Bash内置读取方便地提供了剩余的逻辑:
通过仅在IFS =’ – ‘read -r prop值中指定2个变量,第二个变量值接收第一个=之后的所有内容,无论它是什么,即使它包含其他=实例.

<档案> file.tmp&& mv file.tmp文件是(松散地说)文件的就地更新的常用习惯用法.从技术上讲,修改后的内容会写入临时文件.文件,那个temp.然后文件替换原始文件.

注意:
*需要这种间接的更新方式,因为shell不支持在同一命令中读取和输出到同一文件.
*这个简单的方法可能会有问题,因为如果输入文件是符号链接,它将替换为常规文件,新文件的权限可能不同,…

awk,正如karakfa’s answer所示,肯定是更快的选择,但它带有一个警告 – 这对你来说可能是也可能不是问题:

从概念上讲,属性文件不是严格基于字段的,因为属性值可能包含value-internal = instances.

如果将输入拆分为=,则通用值处理可能会有问题,因为您不会有一个单独的变量作为整体引用该值.

一个简单的例子:假设您有一个输入行foo = bar = baz,并且您希望将字符串@附加到现有值bar = baz,而不必提前知道现有值是否恰好具有embedded = chars.
如果你盲目地使用$2 = $2“@”进行追加,结果值将只是bar @ – 换句话说:你丢失了数据.

解决这个问题需要多做一些工作;这是一个改编自karakfa的awk解决方案,它提供单变量val的全部价值:

awk -F= '
  # Capture the entire value (everything to the right of "=") in variable "val".
  { val= $0; sub("^[^=]+=","",val) }
  $1 == "propertyOne"   { val = "apple/" val } 
  $1 == "propertyTwo"   { sub(///,"/and/",val) }   
  $1 == "propertyThree" { val = val "/end" }
  { print $1 "=" val }  
' file > file.tmp && mv file.tmp file

注意:如果您使用GNU awk且版本号为> = 4.1,则可以使用-i inplace而不是> file.tmp&& mv file.tmp文件就地更新输入文件(松散地说).除了比后一种方法更方便之外,-i inplace还保留了原始文件的权限,但基本方法是相同的:文件被替换,这带来了用常规文件替换符号链接的风险.

sed不是一个好的选择,因为很难以一般方式将替换限制为一部分行.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读