5

我正在尝试从具有某个目录的所有文件中删除特定单词的列表,并将它们替换为任何内容。

所以:

这个很棒的内容 720p BLAH FOO BANG OOO - 30.9.2013.mp4

变成:

这个很棒的内容 - 30.9.2013.mp4

现在,以下内容非常适合单个查找和替换一个单词。

find path/to/folder/ -maxdepth 3 -name '*.*' -execdir bash -c 'mv -i "$1" "${1//foo/}"' bash {} \;

我也尝试了多个发现,但这似乎是一个很长的路要走,而且我似乎以这种方式遇到了问题。

我有几个问题:

  • 希望它不区分大小写
  • 需要 "${1//foo/}" 来引用列表
  • 如果大于 1,则删除空格

尝试在 cronjob 上将其作为 bash 脚本运行。

除非有更好的方法来删除“This Awesome Content”-“30.9.2013.mp4”之间的所有内容。

非常感激。

4

4 回答 4

4

您可以使用“echo”命令将文件名作为变量访问。完成后,进行所需更改的最有效方法是使用“sed”。您可以使用“-e”标志将 sed 命令串在一起。作为 bash 中 for 循环的一部分,这一行为您提供了一个开始。您也可以使用这样的行作为“查找”语句的一部分。

echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI'

获得所需的文件名后,您可以将它们移回原始名称。如果您需要更具体的说明,请告诉我。

更新:这是一个更完整的解决方案。您必须将脚本调整为您自己的文件名等。

for fyle in $(find . -name "*.*")
do 
   mv -i $fyle `echo $fyle | sed -e 's/FOO//gI' -e 's/BANG//gI' `
done

最后,要用一个空白字符替换多个空白字符,您可以添加另一个 sed 命令。这是一个工作命令:

echo "file    input.txt" | sed 's/  */ /g'
于 2013-09-30T14:15:07.280 回答
3

一种方法是添加一个中间步骤,在该步骤中生成一个带有mv命令的文件以实现此目的,然后执行该文件。我假设您有一个words_file包含您不想要的单词的文件。

cd开始前到文件夹

# Create list of valid <file>s in file_list, and list of "mv <file> " commmands
# in cmd_file
ls | grep -f words_file | tee file_list | sed 's/\(.*\)/mv "\1" /g' > cmd_file

# Create the sed statements using the words_file, store it to sed_commands
# Then, apply the sed commands to file_list
sed 's/\(.*\)/s\/\1\/\/g/g' words_file > sed_commands
sed -f sed_commands file_list > new_file_names

# Combine cmd_file and new_file_names to produce the full mv statements
paste cmd_file new_file_names > final_cmds

# To verify the commands
cat final_cmds

# Finally, execute it
sh final_cmds

这是我能想到的,它避免了sed -e为每个单词手动编写。不确定是否有使用常见 bash 实用程序的更简单方法。当然,你可以使用 perl 或者 python,写的更简洁。

编辑:简化它,取消了 eval 和 xargs。

于 2013-09-30T14:44:58.977 回答
1

任务的脚本。它至少接受两个参数,第一个是要从文件名中删除的单词列表,其余的是要处理的文件:

perl -MFile::Spec -MFile::Copy -e '
    $words = join( q{|}, split( q| |, shift ) );
    $words_re = qr{$words}i;
    for $path ( @ARGV ) {
        ($dummy, $dir, $f) = File::Spec->splitpath( $path );
        $f =~ s/$words_re//g;
        $f =~ s/\s{2,}/ /g;
        $newpath = File::Spec->catfile( $dir, $f );
        move( $path, $newpath );
        printf qq|[[%s]] renamed to [[%s]]\n|, $path, $newpath;
    }
' "720p BLAH FOO BANG OOO" tmp/user/*.mp4

在我的测试中,我有以下输出:

[[tmp/user/This Awesome Content 720p BLAH FOO BANG OOO - 30.9.2013.mp4]] renamed to [[tmp/user/This Awesome Content - 30.9.2013.mp4]]
于 2013-09-30T15:27:27.487 回答
0

prename可用于文件重命名部分。stg 类似:

find ... -exec prename 's/(deleteme1|deleteme2|…)//g' {} \;
于 2013-09-30T21:52:00.683 回答