同步不同格式的卷时处理保留字符

同步不同格式的卷时处理保留字符

我有一个 NAS,我想将其上的一些目录复制到 exfat 格式的外部 HDD 上。

问题是路径/文件名可能包含 exfat 的保留字符(请参阅https://en.wikipedia.org/wiki/Filename#Comparison_of_filename_limitations),(但它们是 UTF-8 编码的)例如:

/home/fricadelle/mount_point/my_mp3s/Jake "the snake" O'Brian/03 - is it music ?.mp3

这里“和?”是个问题。直接将此文件夹或文件名 cp -r 到我的硬盘会导致cannot create regular file错误No such file or directory

我还没有找到令人满意的解决方案。这如何批量重命名无效编码的文件或批量替换无效编码字符?建议批量重命名所有内容。我不喜欢这样,因为这些文件在我的 ubuntu 桌面或 mac 或我的网络音频播放器上播放正常。我想将这些字符保留在我的 NAS 中。我想我还必须先将其复制到我的桌面上,然后批量重命名,然后将其复制到我的外部硬盘上。

理想情况下,我希望将某个选项传递给类似 rsync 的程序,以便将所有禁用字符即时映射到空格。这样文件名/文件夹名称只会在我的外部硬盘上更改。

答案1

我必须为我的音乐播放器同步脚本解决这个问题,因为现在是 2020 年,FAT(和 NTFS)仍然无法处理问号或冒号。

PMP同步工具

我选择用 __(双下划线)替换任何 ? 或 : 的实例,因为这可能永远不会产生问题。您可以使用其他类似的解决方案,并且可以扩展可替换字符列表以满足您的需求。

function func_PMP_naughtyFilesystem() { 
    # if the PMP uses FAT or NTFS then sub certain characters with __ 
    printf '%s\n' "Some file systems are unable to handle certain characters.  " 
    printf '%s\n' "FAT and NTFS file systems in particular are bad about this.  " 
    printf '%s\n' "If you would like we can change : and ? into __ to avoid sync failures.  " 
    read -rep "Is your PMP formatted to use one of these lesser file systems?  (Y/n)  " -n1 naughtyFilesystem 
    printf '\n' 
} 

function func_CreateSourceAndDestination() { 
    # 
    for (( i = 0 ; i < ${#files_syncSource[@]} ; i++ )) ; do 
        files_syncDestination[${i}]="${files_syncSource[${i}]#${directory_MusicLibraryRoot_source}}" 
        # printf '%s\n' "${files_syncDestination[${i}]}" # useful in debugging 
        if [ "${naughtyFilesystem}" != "n" ] ; then 
            files_syncDestination[${i}]="${files_syncDestination[${i}]//\:/__}" 
            files_syncDestination[${i}]="${files_syncDestination[${i}]//\?/__}" 
        fi 
        file_destinationPath="$( dirname -- "${directory_PMPRoot_destination}${files_syncDestination[${i}]}" )" 
        if [ ! -d "${file_destinationPath}" ] ; then 
            mkdir -p "${file_destinationPath}" 
        fi 
        # try process substitution 
        # rsync --files-from=<( printf "%s\n" "${files[@]}" ) source destination 
        # rsync -rltDvPm --files-from=<( printf "%s\n" "${files_syncSource[${i}]}" ) "${files_syncDestination[${i}]}" 
        # the above needs to lose the interation and destination should just be PMProot I guess 
        rsync -rltDvPmz "${files_syncSource[${i}]}" "${directory_PMPRoot_destination}${files_syncDestination[${i}]}" 
    done 
} 

首先,我询问用户是否要进行替换,然后,除非他们回答“不”,否则我会在每次同步之前进行这些替换。

如果您有任何疑问,请告诉我。

相关内容