Bash脚本:更新属性文件
propertyOne=1 propertyTwo=a/b propertyThree=three 如何将属性文件的内容更改为以下模式? > propertyOne将在原始值之前添加一个字符串 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内置读取方便地提供了剩余的逻辑: <档案> file.tmp&& mv file.tmp文件是(松散地说)文件的就地更新的常用习惯用法.从技术上讲,修改后的内容会写入临时文件.文件,那个temp.然后文件替换原始文件. 注意: awk,正如karakfa’s answer所示,肯定是更快的选择,但它带有一个警告 – 这对你来说可能是也可能不是问题: 从概念上讲,属性文件不是严格基于字段的,因为属性值可能包含value-internal = instances. 如果将输入拆分为=,则通用值处理可能会有问题,因为您不会有一个单独的变量作为整体引用该值. 一个简单的例子:假设您有一个输入行foo = bar = baz,并且您希望将字符串@附加到现有值bar = baz,而不必提前知道现有值是否恰好具有embedded = chars. 解决这个问题需要多做一些工作;这是一个改编自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不是一个好的选择,因为很难以一般方式将替换限制为一部分行. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |