0

我正在尝试重命名在文件名或文本内容中包含公司名称的文件负载(我数超过 200 个)。我基本上需要将对“公司”的任何引用更改为“新公司”,在适用的情况下保持大写(即“公司变为新公司”,“公司”变为“新公司”)。我需要递归地执行此操作。

因为该名称几乎可以出现在我无法在任何满足我要求的任何地方找到示例代码的任何地方。它可以是这些示例中的任何一个,或者更多:

company.jpg
company.php
company.Class.php
company.Company.php
companysomething.jpg

希望你明白这一点。我不仅需要处理文件名,还需要处理文本文件的内容,例如 HTML 和 PHP 脚本。我假设这将是第二个命令,但我不完全确定是什么。

我搜索了代码库,在近 300 个文件中发现了近 2000 次提及公司名称,所以我不喜欢手动进行。

请帮忙!:)

4

4 回答 4

1

bash具有强大的循环和替换能力:

for filename in `find /root/of/where/files/are -name *company*`; do
    mv $filename ${filename/company/newcompany}
done
for filename in `find /root/of/where/files/are -name *Company*`; do
    mv $filename ${filename/Company/Newcompany}
done
于 2012-06-29T10:58:02.770 回答
1

我建议你看看man rename一个非常强大的 perl 实用程序,用于重命名文件。

标准语法是

rename 's/\.htm$/\.html/' *.htm

聪明的部分是该工具接受任何 perl-regexp 作为要更改的文件名的模式。

您可能希望使用-n开关运行它,这将使该工具仅报告它会更改的内容。

目前无法找到保持大写的好方法,但是由于您已经可以搜索文件结构,因此发出几个rename不同大小写的问题,直到所有文件都被更改。

要遍历当前文件夹下的所有文件并搜索特定字符串,您可以使用

find . -type f -exec grep -n -i STRING_TO_SEARCH_FOR /dev/null {} \;

该命令的输出可以定向到文件(经过一些过滤以仅提取需要更改的文件的文件名)。

find . /type ... > files_to_operate_on

然后将其包装在一个while read循环中并为 inplace-replacement 做一些 perl-magic

while read file
do
    perl -pi -e 's/stringtoreplace/replacementstring/g' $file
done < files_to_operate_on
于 2012-06-29T11:04:43.043 回答
1

对于文件和目录名称,请使用forfind和.mvsed

对于名称中包含的每个路径 ( f) company,将其 ( mv)重命名为替换f为 的新名称。companynewcompany

for f in `find -name '*company*'` ; do mv "$f" "`echo $f | sed s/company/nemcompany/`" ; done

对于文件内容,find使用xargssed

对于每个文件,更改companynewcompany内容,保留带有扩展名的原始文件.backup

find -type f -print0 | xargs -0 sed -i .bakup 's/company/newcompany/g'
于 2012-06-29T11:15:00.147 回答
0

递归处理文件的正确方法很少。这是一个:

while IFS= read -d $'\0' -r file ; do
    newfile="${file//Company/Newcompany}"
    newfile="${newfile//company/newcompany}"
    mv -f "$file" "$newfile"
done < <(find /basedir/ -iname '*company*' -print0)

这将适用于所有可能的文件名,而不仅仅是其中没有空格的文件名。

假设 bash。

对于更改文件的内容,我建议谨慎,因为如果文件不是纯文本,文件中的盲目替换可能会破坏事情。也就是说,sed是为这种事情而制作的。

while IFS= read -d $'\0' -r file ; do
    sed -i '' -e 's/Company/Newcompany/g;s/company/newcompany/g'"$file"
done < <(find /basedir/ -iname '*company*' -print0)

对于这次运行,我建议添加一些额外的开关find来限制它将处理的文件,也许

find /basedir/ \( -iname '*company*' -and \( -iname '*.txt' -or -ianem '*.html' \) \) -print0
于 2012-06-29T13:54:36.187 回答