![](/img/trans.png)
[英]In bash tee is making function variables local, how do I escape this?
[英]How do I reverse escape backslash encodings like “\ ” and “\303\266” in bash?
我有一个脚本,记录UTF8编码名称的文件。 但是,脚本的编码/环境设置不正确,它只是重新编码原始字节。 我现在在文件中有很多行,如下所示:
.../My\ Folders/My\ r\303\266m/...
因此,文件名中有空格,其中包含\\
和UTF8编码的内容,如\\303\\266
(即ö
)。 我想反转这种编码? 是否有一些简单的bash命令行命令可以链接在一起删除它们?
我可以获得数百万个sed
命令,但是要花费很长时间才能列出我们拥有的所有非ASCII字符。 或者开始在python中解析它。 但我希望我能做到一些技巧。
这是对Unicode字符的粗略抨击:
text="/My\ Folders/My\ r\303\266m/"
text="echo \$\'"$(echo "$text"|sed -e 's|\\|\\\\|g')"\'"
# the argument to the echo must not be quoted or escaped-quoted in the next step
text=$(eval "echo $(eval "$text")")
read text < <(echo "$text")
echo "$text"
这使用了Bash的$'string'
引用功能。
这将输出“/ My Folders /Myröm/”。
从Bash 4.4开始,它就像:
text="/My Folders/My r\303\266m/"
echo "${text@E}"
这使用了Bash的一个新功能,称为参数转换 。 E
运算符使得参数被视为其内容在$'string'
中,其中反斜杠转义序列(在本例中为八进制值)被计算。
目前尚不清楚究竟使用了什么类型的转义。 八进制字符代码是C,但C不会逃避空间。 空间转义在shell中使用,但它不使用八进制字符转义。
使用命令printf %b $escaped
可以撤消接近C风格转义的内容。 (文档说八进制转义以\\0
开头,但GNU printf似乎并不需要这样做。)另一个答案提到read
unescaping shell转义,尽管如果空间是唯一一个不由printf %b
处理的那么使用sed
处理这种情况可能会更好。
最后我使用了这样的东西:
cat file | sed 's/%/%%/g' | while read -r line ; do printf "${line}\n" ; done | sed 's/\\ / /g'
有些文件中含有%
,这是一个printf特殊字符,所以我不得不“加倍”,以便它可以被转义并直接通过。 该-r
在read
停止读取逃避\\
的读取但是不转"\\ "
到" "
,所以我需要最终sed
。
使用printf
解决utf-8文本的问题。 使用read
来处理空格(\\ )
。
像这样:
$ text='/My\ Folders/My\ r\303\266m/'
$ IFS='' read t < <(printf "$text")
$ echo "$t"
/My Folders/My röm/
内置的“读取”功能将处理部分问题:
$ echo "with\ spaces" | while read r; do echo $r; done with spaces
将文件(逐行)传递给以下perl脚本。
#!/usr/bin/per
sub encode {
$String = $_[0];
$_ = $String;
while(/(\\[0-9]+|.)/g) {
$Match = $1;
if ($Match =~ /\\([0-9]+)/) {
$Code = oct(0 + $1);
$Char = ((($Code >= 32) && ($Code 160))
? chr($Code)
: sprintf("\\x{%X}", $Code);
printf("%s", $Char);
} else {
print "$Match";
}
}
print "\n";
}
while ($#ARGV >= 0) {
$File = shift();
open(my $F, ") {
$String =~ s/\\ / /g;
&encode($Line);
}
}
像这样:
$ ./PerlEncode.pl Test.txt
Test.txt包含:
/My\ Folders/My\ r\303\266m/
/My\ Folders/My\ r\303\266m/
/My\ Folders/My\ r\303\266m/
行“$ String = ~s / \\ / / g;” 将“\\”替换为“”,子编码解析那些unicode char。
希望这有帮助
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.