繁体   English   中英

变量操作在 macOS bash 脚本中无法按预期工作

[英]Variable Manipulation not working as expected in macOS bash script

鉴于:

itemName='boo\boo\1\7\064.txt'

我想在删除不可打印的同时将八进制转换为可打印的。 问题:我不想删除像 \\b 这样的反斜杠 alpha。 结果应该是:

newItemName='boo\boo4.txt'

我不明白为什么 sed 语句的一部分不能正常工作:

newItemName="$(printf "%s" "$itemName" | sed -E 's/(\\[0-7]{1,3})/'"$(somevar="&";printf "${somevar:1}";)"'/g' | tr -dc '[:print:]')"

我使用了somevar="&"; 而不是直接访问&所以我可以使用变量操作。

搜索语句s/(\\[0-7]{1,3})/工作正常。

在 printf 中,如果我使用$somevar${somevar:0}而不是${somevar:1}我会按预期得到原始字符串(例如 \\064)。 不起作用的是${somevar:1} 这些也不起作用: ${somevar/\\/}${somevar//\\/}

  1. 我对变量操作的工作方式有什么误解?
  2. 有没有更简单的方法来做到这一点? 我已经搜索并搜索了...

山姆; 好久不见! 这里的问题是评估的顺序。 所有 shell 表达式,包括$(somevar="&";printf "${somevar:1}";) ,都会在 sed 启动之前进行评估。 因此, somevar不是正则表达式匹配的字符串,它只是一个文字&符号。 这意味着${somevar:1}只是一个空字符串,你最终只是运行sed -E 's/(\\\\[0-7]{1,3})//g'

您需要一种方法来获取匹配的字符串并对其运行计算(匹配之后),而 sed 不够灵活,无法执行此操作。 但是 perl 是。 perl 有一个s运算符,类似于 sed 的运算符,但使用e选项时,替换将作为 perl 表达式执行,而不仅仅是文字字符串。 试试这个:

newItemName="$(printf "%s\n" "$itemName" | perl -pe 's/\\([0-7]{1,3})/chr oct $1/eg' | tr -dc '[:print:]')"

我对变量操作的工作方式有什么误解?

我相信您误解了sed工作原理。

在替换字符串中使用&字符时,将替换为匹配的整个字符串。 请参阅此 sed 介绍

现在关于${var:offset}参数扩展

somevar=&
printf "$somevar" 

会打印& 然后:

printf "${somevar:1}"

将提取从偏移量 1 开始到字符串末尾的子字符串。 第一个字符在偏移量 0 处,因此在偏移量 1 处没有字符,因为 out 变量somevar有一个字符。 所以它不会打印任何东西。

printf "${somevar:0}"

将打印从偏移量 0 开始到字符串末尾的子字符串。 所以整个字符串。 所以${somevar:0}等于$somevar 它将打印&

所以:

$(somevar="&";printf "${somevar:1}";)

扩展为${somevar:1} ,因为${somevar:1}扩展为${somevar:1} 所以你 sed 命令看起来像这样:

sed -E 's/(\\[0-7]{1,3})//g' 

sed 命令多次替换\\字符后跟数字0-7一到 3 次。 它做你想做的。

现在,如果它是${somevar:0}那么:

$(somevar="&";printf "${somevar:0}";)

扩展为& ,因此您的 sed 命令将如下所示:

sed -E 's/(\\[0-7]{1,3})/&/g' 

所以它会用\\\\[0-7]{1,3}代替它自己 IE。 它什么都不做。

您可以取消-E选项和(...)反向引用,而只需使用 posixly 兼容的sed

sed 's/\\[0-7]\{1,3\}//g'

有没有更简单的方法来做到这一点?

你的方法看起来不错。 您可以使用here 字符串代替 printf ,并且可以根据需要加强 sed 以更好地匹配八进制数:

newItemName="$(
        <<<"$itemName" sed 's/\\\([0-3][0-7]\{0,2\}\|[0-7]\{1,2\}\)//g' |
        tr -dc '[:print:]'
)"

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM