veryverylongfilename.txt
短いファイルシステムに切り替えたいです。NAME_MAX。
mv veryverylongfilename.txt /mnt/tiny
一つ与えてみてエナツロン- タイプエラー:
mv: cannot stat '/mnt/tiny/veryverylongfilename.txt': File name too long
必要に応じてファイル名を切り捨てるにはどのコマンドを使用する必要がありますか?
コマンドが拡張子を保持できる場合は良いでしょう。また、拡張子の前の最後の数文字をすべての種類の一意の識別子に置き換えて移動するときなど、veryverylongfilename1.txt
既存のファイルを上書きしないことをお勧めします。veryverylongfilename2.txt
答え1
次の関数(bashでテスト済み)は、最初の引数を2番目の引数に移動しようとします。最初の引数はファイルで、2番目の引数はディレクトリであると予想してテストします。
ローカル "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
。