如何使用脚本从文件中删除未知的文件扩展名



如果我知道扩展名,我可以删除文件扩展名,例如从文件中删除.txt:

foreach file (`find . -type f`)
mv $file `basename $file .txt`
end

但是,如果我不知道从哪种文件扩展名开始,我将如何做到这一点?

我试过了:

foreach file (`find . -type f`)
mv $file `basename $file .*`
end

但这行不通。

这是什么外壳?至少在 bash 中你可以做到:

find . -type f | while read -r; do
mv -- "$REPLY" "${REPLY%.*}"
done

(通常的警告适用:这不处理名称包含换行符的文件。

您可以使用 sed 来计算基本文件名。

foreach file (`find . -type f`)
mv $file `echo $file | sed -e 's/^(.*).[^.]+$/1/'`
end

请注意:您寻求运行的命令可能会导致数据丢失!

如果您认为文件名不包含换行符或双引号,则可以使用:

find . -type f -name '?*.*' |
sed 's/(.*).[^.]*$/mv "&" "1"/' |
sh

这将生成文件列表(确保名称至少包含一个字符加一个.),通过sed脚本运行每个文件名,通过有效地删除最后一个.的材料,然后通过 shell 运行命令流,将其转换为mv命令。

显然,您首先通过省略| sh部分来测试这一点。 考虑使用| sh -x运行它,以跟踪 shell 正在执行的操作。 请考虑确保将 shell 的输出(标准输出和标准错误)捕获到日志文件中,以便记录发生的损坏。

在开始使用此功能之前,请确保您已备份原始文件集。 它只需要是存储在目录层次结构不同部分的tar文件,您可以在对结果满意后立即将其删除。

你可以选择任何 shell;这不依赖于任何 shell 构造,除了管道、单引号和双引号(对于所有 shell 来说几乎都很常见),而且sed脚本也是版本中立的。

请注意,如果在运行此文件之前xyz.cxyz.h文件,则之后只会xyz一个文件(它包含的内容取决于处理文件的顺序,不必按字母顺序排列)。

如果您认为文件名可能包含双引号(但不包含单引号),则可以在sed脚本中更改引号。 如果可能需要同时处理这两个问题,则需要更复杂的sed脚本。 如果您需要处理文件名中的换行符,那么是时候 (a) 告诉您的用户停止愚蠢和 (b) 修复名称,使它们不包含换行符。 然后,您可以使用上面的脚本。 如果这不可行,你必须更加努力地工作才能准确地完成工作——你可能需要确保你有一个支持-print0find,一个支持-zsed和支持-0xargs(如果你还没有正确的支持,请安装最新的 GNU 版本)。

这很简单:

$ set filename=/home/foo/bar.dat
$ echo ${filename:r}
/home/foo/bar

在"历史替代"中查看更多

r

删除文件扩展名".xxx",保留根名称。

最新更新