【问题标题】:Fixing virtual machine and descriptor file - rewriting vmx [duplicate]修复虚拟机和描述符文件 - 重写 vmx [重复]
【发布时间】:2019-01-30 17:25:10
【问题描述】:

这是 grep -E "scsi0:" *.vmx | 的输出我的目录之一中的 grep -E "fileName" 命令:

scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "P120_vmname_2.vmdk"
scsi0:4.fileName = "P120_vmname_3.vmdk"

我需要在该 vmx 文件中重写上面的输出,使其看起来像以下

scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "vmname_3.vmdk"
scsi0:4.fileName = "vmname_4.vmdk"

所以本质上脚本需要以下内容:

  • 查找包含 scsi0filename 的行并删除 vmname 之前双引号后的所有内容
  • 检查“scsi0:”之后该行中的数字是什么,并在下划线后添加/替换该数字,因此 P120_vmname_2 变为 vmname_3

问题是 vmname 之前可以有任意数量的字符需要删除,需要修复的行可以在源文件中的任何位置。

我需要将单独的行输出分配给单独的变量还是可以只用一个变量来操作它们?

谢谢

【问题讨论】:

标签: arrays linux bash shell


【解决方案1】:

您能否将您的grep 输出通过管道传输到sed

如果是这样,您可以像这样进行替换:

sed -r 's/^(.*:)([[:digit:]]+)(.*) = \".*vmname_[[:digit:]]+/\1\2\3 = \"vmname_\2/'
#           ^        ^         ^       ^             ^          ^              ^
#           |        |         |       |             |          |              Replace number.
#           |        |         |       |             |          Re-create line start
#           |        |         |       |             Match incorrect number                        
#           |        |         |       Match garbage before "vmname"
#           |        |         Match Filename
#           |        Correct number
#           Line start

所以你的实际命令应该是这样的:

grep -E "scsi0:" *.vmx | grep -E "fileName" | \
sed -r 's/^(.*:)([[:digit:]]+)(.*) = \".*vmname_[[:digit:]]+/\1\2\3 = \"vmname_\2/'

转换这个:

scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "P120_vmname_2.vmdk"
scsi0:4.fileName = "P120_vmname_3.vmdk"
scsi0:5.fileName = "P12asdasdsada_asdasd_sdsad0_vmname_3.vmdk"
scsi0:6.fileName = "vmname_3.vmdk"

到这里:

scsi0:0.fileName = "vmname.vmdk"
scsi0:1.fileName = "vmname_1.vmdk"
scsi0:2.fileName = "vmname_2.vmdk"
scsi0:3.fileName = "vmname_3.vmdk"
scsi0:4.fileName = "vmname_4.vmdk"
scsi0:5.fileName = "vmname_5.vmdk"
scsi0:6.fileName = "vmname_6.vmdk"

【讨论】:

  • 卡尔,超级棒!现在我只需要弄清楚如何把 ls *.vmx | sed -e 's/\.vmx$//' 输出(这是没有扩展名的文件名)而不是上面命令中的“vmname”,我们就完成了。 :)
  • @Invisible999 能否在调用 grep/sed 之前将其放入 bash 中的变量中?如果是这样,您可以只使用parameter substitution 将其放入sed 查询而不是"vmname"。您需要更改我的 sed 命令周围的引号,因为单引号不允许替换。
  • 是的。上面的命令看起来超级专业和花哨,但添加更多内容会更难理解并且容易出错。通过将所有内容都放在变量中并有脚本可以调用 - 更易于管理和理解。再次感谢。
  • 这不符合 OP 的要求——即保持所有其他行相同。
猜你喜欢
  • 2023-03-22
  • 1970-01-01
  • 2012-08-21
  • 1970-01-01
  • 1970-01-01
  • 2012-07-18
  • 2018-09-01
  • 2018-04-19
  • 2017-09-05
相关资源
最近更新 更多