我在我的一个Tcl脚本中遇到了一个问题,我将文件从Windows计算机上传到Unix服务器。我想从Windows文件中获取原始文件名,并使用相同的名称保存新文件。问题是[file tail windows_file_name]不起作用,它返回整个文件名,如“c:\ temp \ dog.jpg”,而不仅仅是“dog.jpg”。文件尾部在Unix文件名“/usr/tmp/dog.jpg”上正常工作,因此由于某种原因它没有检测到该文件是Windows格式的。但是,我的Windows计算机上的Tcl可以正常使用任一名称格式。我使用的是Tcl 8.4.18,所以也许它太旧了?还有另一种技巧可以让它正确分割吗?
由于
答案 0 :(得分:1)
这里的问题是,在Windows上,\
和/
都是有效的路径分隔符,因此涉及到很长的Windows API(尽管只有\
被认为是“正式的”视窗)。另一方面,在POSIX中,唯一有效的路径分隔符是/
,并且唯一不能出现在路径名组件中的两个字节是/
和\0
(带有值0)。
因此,在POSIX系统上,“C:\ foo \ bar.baz”是一个完全有效的短文件名,并且正在运行
file normalize {C:\foo\bar.baz}
会产生/path/to/current/dir/C:\foo\bar.baz
。根据相同的逻辑,[file tail $short_filename]
与$short_filename
相同。
解决方案是要么执行Glenn Jackman提出的建议,要么以某种方式通过其他方式从浏览器传递短名称(某些JS绑定到适当的文件条目?)。您也可以尝试从User-Agent标头中检测用户的操作系统。
为了让Glenn的想法对用户的平台更加不可知,你可以这样:
set fname [string map {\\ /} $fname]
,然后转到下一步。[file tail $fn]
提取尾部名称。它不是非常防弹,但据说总比没有好。
答案 1 :(得分:0)
您可以随时[lindex [split $windows_file_name \\] end]