gpt4 book ai didi

bash - 如何在 Perl 中使用 Shell 参数扩展?

转载 作者:行者123 更新时间:2023-12-02 19:33:02 26 4
gpt4 key购买 nike

我正在尝试实现 Bash 参数扩展技术来替换 Perl 脚本中文件的现有扩展名。

这是我的 bash 代码,用于替换文件扩展名,工作正常:

mv "$f" "${f%.*}.png"

另一方面,我尝试使用 system() 在 Perl 脚本中使用它:

system('mv', "$a/$fileName", "$a/${fileName%.*}".'.png');

$a 保存通过命令行参数传递的目录名称。

它抛出“%附近的语法错误”,然后是“字符串中缺少右大括号或方括号”。错误消息中没有 EOF。

当我不使用 %.* 时,它只是在现有文件结尾后附加 .png 但不会替换。我们将非常感谢一些帮助。

最佳答案

所以您希望替换扩展名——以更改文件名。一旦您处于 Perl 脚本中,就没有理由为此使用 shell。

“手动”更改扩展名很容易(请参阅下面的库)。使用正则表达式

my $new_filename = $filename =~ s/.*\.\K.*/$new_extension/r;

.* 贪婪地匹配到最后一个 .(位于模式中),然后 \K 删除所有匹配项这样我们就只替换它后面的内容。或者,使用字符串结尾 anchor $

my $new_filename = $filename =~ s/\.\K[^.]+$/$new_extension/r;

匹配并替换 . 后字符串末尾的所有非 . 字符。在这两种情况下,修饰符 /r 都会使其返回新字符串并保持原始字符串不变;如果没有它,字符串 ($filename) 将就地更改。

现在更改磁盘上文件的名称。标准工具是File::Copy

use File::Copy qw(move);

move $filename, $new_filename or die "Can't move: $!";

(如果您注意到内置 rename 保持冷静并走过它。请参阅其链接页面了解原因。)


当然,最可靠的方法是使用合适的库,并且可以利用一些好的库来实现这一点。这是有用的 Path::Tiny (您需要安装)

use Path::Tiny;

my $path = path($filename);

my $new_fqn = $path->parent->child( $path->basename(qr/[^.]+/) . $new_ext );

请参阅此模块的链接文档,但这里是上述内容的简要说明。

方法 parentPath::Tiny 对象的形式返回到最后一个组件(文件/目录)的路径。然后调用它的方法 child 向其中添加另一个组件。

为此,我们获取basename(最后一个组件,在本次使用中删除了扩展名),然后将新的扩展名附加到其中。瞧,我们找回了替换了扩展名的整个路径。这确实会解析路径两次,一次针对 parent,一次针对 basename

这样做的另一个好处是该模块还有一个 move 方法,因此

$path->move($new_fqn);

完成工作。

该模块检查错误,并发出警告或抛出 its own class 异常.


古老且尝试过的 UNIX 方法是使用核心 File::Basename

use File::Basename;

my ($name, $path, $ext) = fileparse($filename, qr/\.[^.]*/);

my $new_fqn = "$path/$name.$new_ext";

然后使用File::Copy::move重命名文件。

关于bash - 如何在 Perl 中使用 Shell 参数扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61494519/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com