首页 > 解决方案 > 将文件名缩短为 n 个字符,同时保留文件扩展名

问题描述

我试图在保留扩展名的同时缩短文件名。

我认为cut可能是最好的工具,但我不确定如何保留文件扩展名。

例如,我正在尝试重命名abcdefghijklmnop.txtabcde.txt

我想简单地去掉文件名的末尾,以便总字符长度不超过 [在本例中] 5 个字符。

我不关心文件名冲突,因为我的数据集可能不包含任何内容,无论如何我会在重命名任何内容之前进行查找、分析文件和测试。


这样做的背景最终是我想批量截断超过 135 个字符的文件名,以便我可以将文件重新同步到 Synology NAS 上的加密共享。

我找到了一种搜索所有超过 135 个字符的文件名的好方法: find . -type f | awk -F'/' 'length($NF)>135{print $0}'

而且我想将它传递给一个简单的剪切命令,以将文件名缩小到合适的大小。也许有比这更好的方法。我找到了一种在保留扩展名的同时缩短文件名的方法,但我需要递归所有子目录。

任何帮助将不胜感激,谢谢!

更新澄清:

我想使用一个语法如下的单行:

find . -type f | awk -F'/' 'length($NF)>135{print $0}' | some_code_here_to_shorten_the_filename_while_preserving_the_extension

标签: bashsedrenamecutxargs

解决方案


使用 GNU 查找和 bash:

export n=10 # change according to your needs
find . -type f                      \
     ! -name '.*'                   \
       -regextype egrep             \
     ! -regex '.*\.[^/.]{'"$n"',}'  \
       -regex '.*[^/]{'$((n+1))',}' \
       -execdir bash -c '
    echo "PWD=$PWD"
    for f in "${@#./}"; do
        ext=${f#"${f%.*}"}
        echo mv -- "$f" "${f:0:n-${#ext}}${ext}"
    done' bash {} +

这将执行试运行,即显示文件夹,然后显示要在其中执行的命令。一旦您对它的输出感到满意,您就可以echo在之前删除mvecho "PWD=$PWD"如果需要,也可以删除),它实际上会将名称超过n字符的所有文件重命名为与字符长度完全相同的名称,n包括扩展名。

请注意,这不包括隐藏文件,以及扩展名等于或长于n长度(例如.hiddenapp.propertieswhere n=10)的文件。


推荐阅读