我正在研究一个简单的脚本,该脚本在Ubuntu Linux(版本16.04中获取和设置背景,但在这种情况下无关紧要)。问题是我的文件夹名称是UTF-8编码的(特别是中文)。因此,获取当前壁纸的路径失败,如下所示:
my $user_background=qx/gsettings get org.gnome.desktop.background picture-uri/;
print $user_background
的输出:
file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg
因此,问题是:如何从perl中的shell命令获取正确编码/解码的字符串
我试过这个:
my $unicode_String=Encode::decode('utf-8', $user_background );
哪个不起作用。
添加binmode(STDOUT,":utf8");
也无济于事
添加use utf8;
无效
奇怪的是,使用相同的字符串来设置背景确实有效。
答案 0 :(得分:4)
这对我来说是正确的。字符已经过UTF-8编码,然后进行URL编码,因此URL应该正确识别文件。你不应该期望能够阅读它
字符串%E4%B8%8B%E8%BD%BD
对应
- `E4 B8 8B`, which is the character U+4E0B or 下
- `E8 BD BD`, which is the character U+8F7D or 载
下载是“下载”。是吗?
你真的想用字符串做什么?如果您使用picture-filename
而不是picture-uri
答案 1 :(得分:4)
听起来您想要从网址中提取路径。
use open ':std', ':locale';
use feature qw( say );
use Encode qw( decode_utf8 );
use URI qw( );
use URI::Escape qw( uri_unescape );
my $url = URI->new('file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg');
$url->scheme eq 'file'
or die("Invalid input\n");
my $path = decode_utf8( uri_unescape( $url->path ) );
say $path;
作为一个单行:
perl -CS -MEncode=decode_utf8 -MURI -MURI::Escape=uri_unescape \
-e'CORE::say( decode_utf8( uri_unescape( URI->new($ARGV[0])->path ) ) )' \
file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg
由于上一个代码片段采用了UTF-8终端,我们不妨立即避免解码及其后的编码:
perl -MURI -MURI::Escape=uri_unescape \
-e'CORE::say( uri_unescape( URI->new($ARGV[0])->path ) )' \
file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/testimage.jpg
答案 2 :(得分:0)
显然问题出在gsettings
本身。即使在命令行上,它也返回相同的字符串,中文字符未解码。
$ gsettings get org.gnome.desktop.background picture-uri
'file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/ad32d5d0615e9572-121171d86d0c8618-e11082638606a82c303fee0b29697811.jpg'
即使强制环境,它也会返回相同的字符串
$ LC_ALL=C gsettings get org.gnome.desktop.background picture-uri
'file:///home/xieerqi/%E4%B8%8B%E8%BD%BD/ad32d5d0615e9572-121171d86d0c8618-e11082638606a82c303fee0b29697811.jpg'
然而,似乎使用decode_utf8()
方法的子进程输出的正确方法是标量。基本上,这是我尝试过的,并成功获得输出
#!/usr/bin/env perl
use strict;
use warnings;
use utf8;
use Encode;
my $stuff=qx/ls ~ /;
my $utf_string = decode_utf8( $stuff );
print "$utf_string";