将文件移动到具有较短 NAME_MAX 的文件系统时,如有必要,请截断

将文件移动到具有较短 NAME_MAX 的文件系统时,如有必要,请截断

我想转移veryverylongfilename.txt到一个短文件系统NAME_MAX

mv veryverylongfilename.txt /mnt/tiny给我一个埃纳图隆- 类型错误:

mv: cannot stat '/mnt/tiny/veryverylongfilename.txt': File name too long

如果需要的话,我应该使用什么命令来截断文件名?

如果该命令可以保留扩展名,那就太好了。此外,最好避免覆盖现有文件,例如在移动veryverylongfilename1.txtthen 时veryverylongfilename2.txt,通过使用任何类型的唯一标识符代替扩展名之前的最后几个字符。

答案1

以下函数(在 bash 中测试)将尝试将其第一个参数移动到第二个参数。它期望(并测试)第一个参数是文件,第二个参数是目录。

本地“namemax”变量应调整为您的文件系统的NAME_MAX.

moveshort() {
  local namemax=8

  # simple sanity checks
  [ "$#" -eq 2 ] || return 1
  local src=$1
  [ -e "$src" ] || return 2
  local dest=$2
  [ -d "$dest" ] || return 3

  local extension=${src##*.}
  local basename=${src%.*}
  # the base name has ($namemax - $extension - 1)
  # characters available to it (1 for the period)
  local maxbase=$((namemax - ${#extension} - 1))

  # shorten the name, if necessary
  basename=${basename:0:maxbase}

  # echo "Shortened name: ${basename}.${extension}"
  # find a new name, if necessary
  if [ -e "${dest}/${basename}.${extension}" ]
  then
    local index=1
    local lenindex=${#index}
    #local newbase=${basename:0:-lenindex}
    local newbase=${basename:0:maxbase - lenindex}
    # loop as long as a conflicting filename exists and
    # we're not out of space in the filename for the index
    while [ -e "${dest}/${newbase}${index}.${extension}" -a "${#index}" -lt "$maxbase" ]
    do
      index=$((index + 1))
      lenindex=${#index}
      newbase=${newbase:0:maxbase - lenindex}
    done
    if [ -e "${dest}/${newbase}${index}.${extension}" ]
    then
      echo "Failed to find a non-colliding new name for $src in $dest" >&2
      return 4
    fi
    basename=${newbase}${index}
    # echo "new name = ${basename}.${extension}"
  fi

  # perform the move
  mv -- "$src" "${dest}/${basename}.${extension}"
}

健全性检查后,该函数保存扩展名和剩余的基本文件名,然后确定基本文件名可以使用多少个字符。

如果给定的文件名已经太长,那么我们会删除多余的字符。

如果缩短的名称已存在于目标中,则我们开始循环,从 1 开始,生成新的基本文件名,直到基本文件名空间不足或找到不存在的文件。随着索引的增长,新的基本文件名会被索引压缩。

如果文件名空间不足,该函数会回显错误并返回;否则,它会尝试执行mv.

相关内容