变量操作在macOS bash脚本中未按预期工作
鉴于: 我想在删除不可打印内容的同时将八进制转换为可打印内容。问题:我不想删除像\b这样的反斜杠字母。结果应该是:变量操作在macOS bash脚本中未按预期工作,bash,macos,sed,Bash,Macos,Sed,鉴于: 我想在删除不可打印内容的同时将八进制转换为可打印内容。问题:我不想删除像\b这样的反斜杠字母。结果应该是: itemName='boo\boo\1\7\064.txt' 我不明白为什么sed语句的一部分不能正常工作: newItemName='boo\boo4.txt' 我使用了somevar=“&”而不是直接访问和,因此我可以使用变量操作 搜索语句s/(\[0-7]{1,3})/工作正常 在printf中,如果我使用$somevar或${somevar:0}而不是${somevar
itemName='boo\boo\1\7\064.txt'
我不明白为什么sed语句的一部分不能正常工作:
newItemName='boo\boo4.txt'
我使用了somevar=“&”而不是直接访问和,因此我可以使用变量操作
搜索语句s/(\[0-7]{1,3})/工作正常
在printf中,如果我使用$somevar或${somevar:0}而不是${somevar:1}我会得到预期的原始字符串(例如.\064)。
不起作用的是${somevar:1}。
这些也不起作用:${somevar/\/}或${somevar/\/}
&
字符时,它将被匹配的整个字符串替换。看
现在关于:
将打印&
。然后:
somevar=&
printf "$somevar"
将从偏移量1到字符串末尾提取子字符串。第一个字符位于偏移量0处,因此在偏移量1处没有字符,因为out变量somevar
有一个字符。所以它不会打印任何内容
printf "${somevar:1}"
将打印从偏移量0开始到字符串末尾的子字符串。因此,整个字符串。所以${somevar:0}
等于$somevar
。它将打印&
因此:
扩展为零,因为${somevar:1}
扩展为零。因此,sed命令如下所示:
$(somevar="&";printf "${somevar:1}";)
$(somevar="&";printf "${somevar:0}";)
sed命令将一个\
字符后跟一个数字0-7
一到三次替换为零,多次。它做你想要的
现在,如果它是${somevar:0}
,那么:
sed -E 's/(\\[0-7]{1,3})//g'
扩展到&
,因此您的sed命令如下所示:
$(somevar="&";printf "${somevar:1}";)
$(somevar="&";printf "${somevar:0}";)
因此它将用一个\\[0-7]{1,3}
来代替它本身。它什么也没做
您可以松开-E
选项和(…)
反向引用,只需使用posixly兼容的sed
:
sed -E 's/(\\[0-7]{1,3})/&/g'
有没有更简单的方法
你的方法看起来不错。您可以使用a而不是printf,并且可以根据需要加强sed以更好地匹配八进制数:
sed 's/\\[0-7]\{1,3\}//g'
newItemName=”$(
Sam;好久不见!这里的问题是求值顺序。所有的shell表达式,包括$(somevar=“&”printf“${somevar:1}”)
,都是在sed启动之前求值的。因此,somevar
不是正则表达式匹配的字符串,它只是一个文字符号。这意味着${somevar:1}
只是一个空字符串,您只需运行sed-E/(\\[0-7]{1,3})//g'
您需要一种方法来获取匹配的字符串并对其运行计算(在匹配后),sed不够灵活。但是perl是。perl有一个s
操作符,与sed类似,但是使用e
选项,替换将作为perl表达式而不是文字字符串执行。请尝试一下:
newItemName="$(
<<<"$itemName" sed 's/\\\([0-3][0-7]\{0,2\}\|[0-7]\{1,2\}\)//g' |
tr -dc '[:print:]'
)"
sed-E
-请检查您在macos上是否有sed-E
。似乎没有-E.@SamuelHerschbein,这只会产生一个文本&
,因此这就是传递给sed
作为替换的内容。尝试在它之前运行set-x
(在macOS上,unset PROMPT_命令
删除后台聊天),shell将打印其实际执行的内容。使用set+x
将其关闭。
newItemName="$(printf "%s\n" "$itemName" | perl -pe 's/\\([0-7]{1,3})/chr oct $1/eg' | tr -dc '[:print:]')"