shell 使用bash sed命令替换双反斜杠

xytpbqjk  于 2023-08-07  发布在  Shell
关注(0)|答案(1)|浏览(229)

加载前面的管道工件进行检查(文件名为cache_deploy_.properties)。该文件包含每个模块和最后更改的时间戳。如果模块在上一次运行后发生了更改,则会使用时间戳(hashcode)更新文件(是的,类似于Git提交)。更新此文件后,它将作为管道工件发布,供下次运行使用。
文件内容示例

#Tue Aug 01 11:09:53 AEST 2023
D\:\\agent_work\\agent-2\\168\\s\\PRIE\\Programs\\IEW340P3.NSP=ec656d00d2e5e12ae1eb3aa9771af464\!\:\!null
D\:\\agent_work\\agent-2\\168\\s\\PRMR\\Maps\\MRJ400M1.NSM=c4b10568d2dd5f88f255cf0192b0945d\!\:\!null

字符串
实际情况是,下一次管道运行时,azure的“用户代理”是不同的,因此文件中检查的模块被认为是不同的位置

echo $(System.DefaultWorkingDirectory)
D\:\\agent_work\\agent-1\\217\\s\\    ----> (compared to previous run as above D\:\\agent_work\\agent-2\\168\\s\\)


所以当它去检查这个文件时,记录的信息将不再匹配(作为文件中不同的“用户代理”)。管道将尝试为每个模块创建新条目。我无法控制文件的输出...否则我会删除用户代理(来自供应商的专有JAR和Ant脚本)。它在分析中使用完整的文件位置来确定如何处理更改的模块。
这是为了达到...需要重命名文件中的所有行,使用以前的“用户代理”来匹配当前的“用户代理”在管道构建中使用bash脚本来更改工件加载文件中的用户代理。我正在尝试以下内容,但可能需要一些帮助。
脚本示例

echo '#Tue Aug 01 14:16:13 AEST 2023
D\:\\agent_work\\agent-2\\168\\s\\PRIE\\Programs\\IEW340P3.NSP=ec656d00d2e5e12ae1eb3aa9771af464\!\:\!null
D\:\\agent_work\\agent-2\\168\\s\\PRUT\\Maps\\UTRESM06.NSM=eb0e29846516c74be5763a8cd9ab22d8\!\:\!null
D\:\\agent_work\\agent-2\\168\\s\\PRMR\\Maps\\MRJ400M1.NSM=c4b10568d2dd5f88f255cf0192b0945d\!\:\!null' > myconfig.txt
file="myconfig.txt"

# userAgent='D\:\\agent_work\\agent-2\\168\\s\\' #This is user agent is in the file no need for fixing!
userAgent='D\:\\agent_work\\agent-1\\170\\s\\'
echo "Current User agent:" $userAgent

if grep -F $userAgent $file; then
    echo "Found user agent, no need to replace"
else
    echo "User Agent not found in file, need to replace with current"
    var=$(sed '2q;d' $file) # just need to check for prev agent on 2nd line
    substr="s" # this 's' is the end position of the agent 
    prefix=#${var%%$substr*} #gives us the index nuumber of 's'
    index=$((${#prefix}+2)) # add 2 to cater for the // after s
    replaceUser=${var:0:index} #finally have the string to search the file for to replace
    echo "Previous user agent:" $replaceUser

    sed -i --debug "s/'$replaceUser'/$userAgent/g" $file # <-- This is not working
fi
Output:
Current User agent: D\:\\agent_work\\agent-1\\170\\s\\
User Agent not found in file, need to replace with current
Previous user agent: D\:\\agent_work\\agent-2\\168\\s\\P
SED PROGRAM:
  s/'D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\P'/D:\agent_work\agent-1\170\s\/g
INPUT:   'myconfig.txt' line 1
PATTERN: #Tue Aug 01 14:16:13 AEST 2023
COMMAND: s/'D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\'/D:\agent_work\agent-1\170\s\/g
PATTERN: #Tue Aug 01 14:16:13 AEST 2023
END-OF-CYCLE:
INPUT:   'myconfig.txt' line 2
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRIE\\\\Programs\\\\IEW340P3.NSP=ec656d00d2e5e12ae1eb3aa9771af464\\!\\:\\!null
COMMAND: s/'D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\'/D:\agent_work\agent-1\170\s\/g
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRIE\\\\Programs\\\\IEW340P3.NSP=ec656d00d2e5e12ae1eb3aa9771af464\\!\\:\\!null
END-OF-CYCLE:
INPUT:   'myconfig.txt' line 3
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRUT\\\\Maps\\\\UTRESM06.NSM=eb0e29846516c74be5763a8cd9ab22d8\\!\\:\\!null
COMMAND: s/'D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\'/D:\agent_work\agent-1\170\s\/g
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRUT\\\\Maps\\\\UTRESM06.NSM=eb0e29846516c74be5763a8cd9ab22d8\\!\\:\\!null
END-OF-CYCLE:
INPUT:   'myconfig.txt' line 4
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRMR\\\\Maps\\\\MRJ400M1.NSM=c4b10568d2dd5f88f255cf0192b0945d\\!\\:\\!null
COMMAND: s/'D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\'/D:\agent_work\agent-1\170\s\/g
PATTERN: D\\:\\\\agent_work\\\\agent-2\\\\168\\\\s\\\\PRMR\\\\Maps\\\\MRJ400M1.NSM=c4b10568d2dd5f88f255cf0192b0945d\\!\\:\\!null
END-OF-CYCLE:

的字符串

替换字符串中没有使用完整的反斜杠,看起来sed与字符串替换的模式不匹配。

最终的结果应该是文件被替换为正确的字符串,包括匹配和保留双反斜杠使用bash

rslzwgfq

rslzwgfq1#

替换字符串中未使用完整的反斜杠,sed似乎与字符串替换的模式不匹配。

特别是:

sed -i --debug "s/'$replaceUser'/$userAgent/g" $file # <-- This is not working

字符串
我敢肯定这是行不通的。至少,该命令中的单引号位于双引号内,因此表示它们自己。您的文件不包含相应的单引号字符,因此没有任何行与该正则表达式匹配。此外,userAgent的扩展中的反斜杠不会被sed从字面上理解,因此您将得到不正确的替换。(而且,至少我的sed不理解--debug。)
反斜线是sed的转义字符。“要表示文字反斜杠,请使用双反斜杠(\\)。
反斜杠也是shell的转义字符,但通过使用单引号将其引起来,可以有效地实现此目的。
您的原始代码通过混合使用sed的命令替换和几个bash参数扩展来从文件中确定旧的用户代理,然后尝试构造sed表达式以使用新的代理字符串替换旧的代理字符串。但是您已经在使用sed了,而且用户代理标识就在它的驾驶室里,那么您为什么要把它弄得这么复杂呢?
你可能简化了一个更复杂的真实场景,但根据你实际展示的内容,我可能会做更多类似于以下内容的事情:

#!/bin/bash

file=myconfig.txt
userAgent='D\:\\agent_work\\agent-1\\170\\s\\'
echo "Current User agent: $userAgent"

if grep -q -F "$userAgent" "$file"; then
    echo "Found user agent, no need to replace"
else
    echo "User Agent not found in file, need to replace with current"
    sed -i -e '2,$s/^[^s]*s\\\\/'"${userAgent//\\/\\\\}/" "$file"
fi


事实上,我甚至可以去掉用户代理测试,无条件地进行替换:

#!/bin/bash

file=myconfig.txt
userAgent='D\:\\agent_work\\agent-1\\170\\s\\'

sed -i -e '2,$s/^[^s]*s\\\\/'"${userAgent//\\/\\\\}/" "$file"


它使用的方法与您最初选择当前用户代理字符串的方法大致相同(从行首到第一个“s”后跟双反斜杠的所有内容,而不考虑反斜杠,直到第一个“s”的所有内容),并且它用所选的用户代理字符串替换第二行和所有后续行上的用户代理字符串。
这里的主要技巧是在sed表达式中加倍反斜杠,包括$userAgent的文字部分和扩展部分。字面部分按字面处理,$userAgent部分具有shell参数扩展的模式替换功能。${userAgent//\\/\\\\}表示shell参数userAgent的值,所有出现的模式\\(不加引号,表示 * 一个 * 反斜杠字符)都被\\\\(不加引号,表示 * 两个 * 反斜杠字符)替换。
然而,也要注意引用的细节,因为你的原始脚本有些引用不足。
如果您需要(由于问题中不明显的原因)更接近原始代码,那么您应该能够在原始代码中使用相同类型的替换。也许用这样的东西:

sed -i --debug "s/${replaceUser//\\/\\\\}/${userAgent//\\/\\\\}/" "$file"

相关问题