阅读列表时如何从文件名中删除指定术语?

阅读列表时如何从文件名中删除指定术语?

我正处于个人项目这一阶段的开始阶段。我有大量的视频文件,其中散布着“1980p”、“webrip”等术语,我想将其删除。

从命令行使用 perl rename 就足够简单了,或者可以使用带有 GUI 的重命名器来完成,但缺点是每次更改目录或启动新会话时,最终都会一遍又一遍地输入相同的信息再次。

首先 - 我正在使用 zsh。其次 - 我可以成功地将点、空格、破折号等转换为下划线,这样文件/文件夹名称中就没有空格。

第三 - 我将所有文件/文件夹名称转换为小写以简化任务。

第四 - 要么我做错了什么,要么 shell 中的递归可能会命中或错过,所以我将逐个文件夹进行操作。

use strict;
use warnings;

while read i
do
my $i=$(echo $i)
find . -iname "*$i*" rename 's/"$i"//' {} \;
done < /home/terry/.local/bin/Persistent_File_Renamer/persistent_data.txt

给我“全局”警告。

我找到了这个,但它只是关闭了终端。

if [ $# != 1 ]; then
    echo "Usage: $0 input-file"
    exit 1
else
    infile=$1
fi

exec 3< /home/terry/.local/bin/Persistent_File_Renamer/persistent_data.txt

until [ $done ]
do
    read <&3 myline
    if [ $? != 0 ]; then
        done=1
        continue
    fi
    # process file data line-by-line
    # in here ...
    rename 's/"$myline"//' ./"*$myline*"
done

echo "The End"

我不是菜鸟,但我在这里束手无策。我对方法没有偏好,只要我最终得到一个可重用、可编辑、换行结束的列表。

谢谢。

答案1

如果您可以使用zshperl ,则不需要 perl renamezsh的功能zmv同样强大且更可靠。

autoload -Uz zmv
strings_to_remove=(
  ${(f)"$(<~/.local/bin/Persistent_File_Renamer/persistent_data.txt)"}
) &&
  zmv -n '(**/)(*)' '$1${${(L)2//[. _-]##/_}//(${(~j[|])strings_to_remove})}'

在哪里:

  • ${(f)"$(<file)"}在换行符上分割文件的内容并丢弃空行,此处分配给一个数组。
  • zmv将与模式匹配的所有文件(**/)(*)(任何级别的非隐藏目录中的任何非隐藏文件)重命名为第二个参数中的代码扩展,深度优先。
  • ${(L)2}$2将(此处捕获文件的基本名称)转换为小写。
  • ${var//[. _-]##/_}_将 1 个或多个、.-空格字符 的序列替换为 1 _
  • ${(~j[|])array} joins 数组的元素|,但 with~|视为通配符运算符而不是文字|

如果满意,请删除-n(试运行)。

请注意,因为它会立即替换所有字符串,所以如果您有strings_to_remove=(worst bad)一个名为 的文件名wobadrst.txt,它将被替换为worst_txt,并且worst不会被删除。你的方法也会发生同样的情况。

使用rename来自 perl 的File::Rename,假设 UTF-8 编码的文件名,您可以执行类似的操作

find . -depth ! -name . -print0 |
  LIST=~/.local/bin/Persistent_File_Renamer/persistent_data.txt \
  PERL_UNICODE=S rename -n -0 -d '
    use vars qw($pattern);
    BEGIN {
      open LIST, "<", $ENV{LIST} or die "$ENV{LIST}: $!\n";
      chomp(my @strings_to_remove = grep {!/^$/} <LIST>);
      our $pattern = join "|", map {qr{\Q$_\E}} @strings_to_remove;
    }
    s/[_ .-]+/_/g;
    $_ = lc $_;
    s/$pattern//g'

无论如何,您都不想将 shell 变量的扩展嵌入到 perl 代码中,这将是一个命令注入漏洞。您可以通过环境将数据传递到 perl 脚本,就像我们在这里为$ENV{LIST}文件所做的那样。

相关内容