2014-02-20 63 views
0

我的脚本执行以下操作:复制文件

./myscript pathfile.txt 
  • 安装包含文件系统到/ mnt /文件系统/图像文件。

在浏览路径是这样的:

/mnt/filesystem/Windows/somefile.exe 
/mnt/filesystem/Program Files/somefile.exe 
  • 搜索pathfile.txt并从该文件中的所有路径。

提取的路径是这样的:

C:\windows\somefile.exe 
C:\program Files\somefile.exe 
  • 然后我尝试的路径从pathfile.txt转换成适合我的Systempath下,所以我可以从/mnt/filesystem/的.exe文件复制出来。

  • 从行中删除3个第一个字符,删除C :.

  • 在\上使用replace,将其设置为/。
  • 添加安装目标。

现在的路径是这样的:

/mnt/filesystem/windows/somefile.exe 
/mnt/filesystem/program files/somefile.exe 

我试着使用路径名要复制的文件,但它不会因为路径间距的工作,大/小写等

所以我的问题:

如何动态适应路径差异,当涉及到大/小写,间距等?

我现在试图复制/mnt/filesystem/program files/somefile.exe这确实是在/mnt/filesystem/"Program Files"/somefile.exe,使用subprocess.call

我真的很陌生,所以请给我一些简单的例子。谢谢

UPDATE:

我做了一个小的脚本了我很大的剧本和制作的东西根据您的输入塞巴斯蒂安我能理解,到现在我有下面的代码。但是,代码似乎无法正常工作。该脚本正在运行,但没有文件正在被复制。

Argument = pathfile.txt 

fileName = sys.argv[1] 
inputFile = open(fileName, "r") 
paths = inputFile.read() 

src_dir = "/mnt/filesystem/" 
dest_dir = "/home/user/copyhere/" 

for path in re.finditer('(c(?i):\\\.*?\.exe)', paths): 
    hits = path.groups() 
for line in hits: 
    line = line.replace("\\", "/").lower() 
    line = ntpath.splitdrive(line)[1].lstrip("\\/") 
    assert src_dir.endswith(os.path.sep) 
for root, dirs, files in os.walk(src_dir): 
    for filename in files: 
    path = os.path.join(root, filename) 
    normalized_path = path[len(src_dir):].lower() 
    if normalized_path in paths: 
     shutil.copy(path, dest_dir) 
     paths.remove(normalized_path) 
     if not paths: 
     sys.exit() 

#As mentioned the pathfile.txt is not neat and tidy, its a real mess, therefore im using regex to extract the paths. 
#BELOW ARE HOW THE OUTPUT LOOKS LIKE: 
#Real path:/mnt/filesystem/Program Files/ESET/ESET NOD32 Antivirus/somefile.exe 
#Script path: /mnt/filesystem/program files/eset/eset nod32 antivirus/somefile.exe 
#Real path: /mnt/filesystem/Program Files/Elantech/somefile.exe 
#Script path: /mnt/filesystem/program files/elantech/somefile.exe 
#Real path: /mnt/filesystem/Program Files (x86)/ATI Technologies/ATI.ACE/Core-Static/somefile.exe 
#Script path: /mnt/filesystem/program files (x86)/ati technologies/ati.ace/core-static/somefile.exe 
+0

感谢去除不值得回答(谁,我忘了记住用户名),但这样一来这个问题保持解答,并从而得出比标记为答案但答案根本没有帮助的问题更受关注。 – Alfe

+0

我认为你的意思是说你有一个你装载的文件系统和一个文本文件,其中列出了这个文件系统中的路径。那是对的吗?然后,如果您在Unix系统中安装该文件系统,则应该在安装点之下具有路径,因为它们在文本文件中。 _only_不同之处应该是前缀'C:'和反斜杠''''''将会斜杠'/'。空格和上/下字符应保持不变。你能证实你的情况吗? – Alfe

+0

缩进在Python中很重要。你的问题中的代码产生'IndentationError'。 – jfs

回答

0

念起来要复制原来如此其中有区分大小写的文件系统的系统上不敏感的的Windows路径,你可以依靠的Windows不允许用户创建第二个文件只在不同的情况下,允许比较使用标准化病例,以创建一个映射路径:

"path from pathfile.txt" -> "mounted path on case-sensitive filesystem" 

你可以使用,甚至在Unix ntpath模块操作的Windows路径例如为:

>>> import ntpath 
>>> ntpath.splitdrive('C:\windows\somefile.exe') 
('C:', '\\windows\\somefile.exe') 
>>> ntpath.normcase('C:\program Files/somefile.exe') 
'c:\\program files\\somefile.exe' 

不应该有在道路空间的任何问题,如果你正确使用subprocess.call()。虽然您不需要subprocess.call()复制文件;你可以使用shutil.copy()代替:

#!/usr/bin/env python 
import ntpath 
import os 
import shutil 
import sys 

def normalize(path): 
    path = path.strip() 
    path = ntpath.splitdrive(path)[1].lstrip("\\/") # remove C:\ or C:/ 
    return path.replace("\\", "/").lower() 

# get non-blank lines and normalize paths 
with open(sys.argv[1]) as pathfile: 
    paths = set(filter(bool, map(normalize, pathfile))) 

# find the paths in the source directory tree & copy them to the destination 
src_dir = "/mnt/filesystem/"  # where to copy from 
assert src_dir.endswith(os.path.sep) # needed for `path[len(src_dir):]` below 
dest_dir = "/destination/directory" # where to copy to 
for root, dirs, files in os.walk(src_dir): # traverse directory tree 
    for filename in files: 
     path = os.path.join(root, filename) 
     normalized_path = path[len(src_dir):].lower() 
     if normalized_path in paths: # path is from pathfile.txt 
      shutil.copy(path, dest_dir) # copy 
      paths.remove(normalized_path) 
      if not paths: # no more paths to copy 
       sys.exit() 

(未测试)

+0

看着这个我的输出不能真正看到它做了什么不同,然后我已经有了。路径看起来不错,但是它仍然不会根据正确的路径找到我的文件,因为实际路径在目录名称中使用大写或小写。 – user3323307

+0

@ user3323307:添加到代码“print(paths)'和'print(normalized_pa​​th)'并发布结果。比较是不区分大小写的 - 它在两个地方调用'.lower()'的目的:1.将所有路径从'pathfile'转换为小写2.在从src_dir'搜索它们之前,将路径从'src_dir'转换为小写'路径'设置。我的猜测是,你错误地从'pathfile'解析了路径。如果是这种情况,那么1.编写脚本,除了在pathfile_good中每行写一条路径之外,什么都不做。2.将这个文件放到我的脚本中。 – jfs

+0

运行你与pathfile看起来像这样原来的脚本: C:\ Program Files文件\ ESET \ ESET NOD32防病毒\ egui.exe C:\ Program Files文件\ elantech \ etdctrl.exe 结果的路径是: 集( [ '程序文件/ elantech/etdctrl.exe \ n' 等 结果路径的是(正确的!): 到/ mnt /文件系统/ Program Files文件/ ESET/ESET NOD32防病毒/ egui.exe等 结果normalized_pa​​th是: 程序文件/公用文件/ ati技术/多媒体/ amdh264enc32.dll等 我只是不知道最新错误/ mnt/filesystem /是只读的,但我想更改ar只有在记忆中。 – user3323307

0

不用手动得到这些路径,并试图确定如何处理大/小写的项目,我会建议使用内置Python中os模块。这样操作系统实际上告诉你的位置。以下是获取当前工作目录,Program Files目录以及相关的绝对和相对引用的示例。

>>> import os 
>>> print os.getcwd() 
C:\Users\sheindel 
>>> print os.environ["ProgramFiles"] 
C:\Program Files 
>>> print os.path.abspath(os.environ["ProgramFiles"]) 
C:\Program Files 
>>> print os.path.relpath(os.environ["ProgramFiles"]) 
..\..\Program Files 

请记住,如果它是64位机器,您将拥有两个不同的程序目录。上述示例将获得32位系统上的Program Files目录,它将在64位系统上获得64位Program Files目录。如果在64位系统上,下面的代码将获得32位Program Files文件

>>> print os.getcwd() 
C:\Users\sheindel 
>>> print os.environ["ProgramFiles(x86)"] 
C:\Program Files (x86) 
>>> print os.path.relpath(os.environ["ProgramFiles(x86)"]) 
..\..\Program Files (x86) 
>>> print os.path.abspath(os.environ["ProgramFiles(x86)"]) 
C:\Program Files (x86) 

花一些时间对python docs on the os module和os.path中

python docs on the os.path module专门
+0

感谢您的投入StephenH。我不太清楚如何将它与输入文件一起使用。你有一个例子吗?查看我的更新。 – user3323307