如果我知道扩展名,我可以删除文件扩展名,例如从文件中删除.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.c
和xyz.h
文件,则之后只会xyz
一个文件(它包含的内容取决于处理文件的顺序,不必按字母顺序排列)。
如果您认为文件名可能包含双引号(但不包含单引号),则可以在sed
脚本中更改引号。 如果可能需要同时处理这两个问题,则需要更复杂的sed
脚本。 如果您需要处理文件名中的换行符,那么是时候 (a) 告诉您的用户停止愚蠢和 (b) 修复名称,使它们不包含换行符。 然后,您可以使用上面的脚本。 如果这不可行,你必须更加努力地工作才能准确地完成工作——你可能需要确保你有一个支持-print0
的find
,一个支持-z
的sed
和支持-0
的xargs
(如果你还没有正确的支持,请安装最新的 GNU 版本)。
这很简单:
$ set filename=/home/foo/bar.dat
$ echo ${filename:r}
/home/foo/bar
在"历史替代"中查看更多
:r
删除文件扩展名".xxx",保留根名称。