我正在使用Mathematica处理大量网站文件,这些文件已镜像到我自己的系统上。它们分布在数百个目录中,其中包含大量子目录。因此,例如,我有:
/users/me/test/directory1
/users/me/test/directory1/subdirectory2 [times a hundred]
/users/me/test/directory2
/users/me/test/directory2/subdirectory5 [etc. etc.]
我需要做的是进入每个目录,将所有HTML文件
Import[]
编码为Plaintext,然后将它们放在系统上其他以“directory1”命名的目录中。到目前为止,通过Do[]
循环,我已经能够进行一个粗略的版本:但是,我目前最好的情况是将“.txt”文件转储到原始目录中,这不是理想的解决方案,因为它们是仍然遍布我的系统。要找到我的文件,我使用
directoryfiles = FileNames["*.htm*", {"*"}, Infinity];
一些其他令人烦恼的问题:
(1)重复项:Mathematica是否可以处理重复项-即,如果遇到另一个index_en.html,可以将其重命名为index_en_1.html吗?
(2)目录:由于存在所有目录,除非我使用Mathematica一遍又一遍地不断
SetDirectory
和CreateDirectory
,否则它总是会遇到麻烦。这一切似乎有点令人困惑。基本上,Mathematica是否有一种有效的方法来查找分布在数百个目录/子目录中的大量HTML文件,将它们导入为纯文本,然后将它们导出到其他位置[对我来说很重要,他们要知道它们来自directory1,仅此而已] 。
-为清晰起见,在下面进行了编辑-
这是我目前拥有的代码:
SetDirectory[
"/users/me/web/"];
dirlist = FileNames[];
directoryPrefix =
"/users/me/web/";
plainHTMLBucket = "";
Do[
directory = directoryPrefix <> dirname;
exportPrefix =
"/users/me/desktop/bucket/";
SetDirectory[directory];
allFiles = FileNames["*.htm*", {"*"}, Infinity];
plainHTMLBucket = "";
Do[
plainHTML = Import[filename, "Plaintext"];
plainHTMLBucket = AppendTo[plainHTMLBucket, plainHTML];
, {filename, allFiles}];
Export[exportPrefix <> dirname <> ".txt", plainHTMLBucket];
Print["We Have Reached Here"];
, {dirname, dirlist}];
从我的角度来看这有什么问题?除了凌乱之外,这是我的解决方法:我宁愿将所有文件都分开而不是一个大文件-即,将每个导入和导出作为一个单独的文件,但是放在一个名为“directory1”的目录中,尽管位于其他位置。问题是要镜像这些目录(目录不存在,但是我无法使用
CreateDirectory[]
动态地这样做)。我对此感到困惑表示歉意-我知道这表明了这个问题。
最佳答案
以下代码可以解决问题:
mapFileNames[source_, filenames_, target_] :=
Module[{depth = FileNameDepth[source]}
, FileNameJoin[{target, FileNameDrop[#, depth]}]& /@ filenames
]
htmlTreeToPlainText[source_, target_] :=
Module[{htmlFiles, textFiles, targetDirs}
, htmlFiles = FileNames["*.html", source, Infinity]
; textFiles = StringReplace[
mapFileNames[source, htmlFiles, target]
, f__~~".html"~~EndOfString :> f~~".txt"
]
; targetDirs = DeleteDuplicates[FileNameDrop[#, -1]& /@ textFiles]
; If[FileExistsQ[target], DeleteDirectory[target, DeleteContents -> True]]
; Scan[CreateDirectory[#, CreateIntermediateDirectories -> True]&, targetDirs]
; Scan[
Export[#[[2]], Import[#[[1]], "Plaintext"], "Text"] &
, Transpose[{htmlFiles, textFiles}]
]
]
使用示例(警告:将首先删除目标目录!):
htmlTreeToPlainText["/users/me/web", "/users/me/desktop/bucket"]
工作原理
在这种情况下,各种Mathematica
FileName...
函数很有帮助。首先,我们首先定义辅助函数mapFileNames
,该函数带有源目录,位于源目录内的文件名列表和目标目录。它返回文件路径列表,该文件路径命名目标目录下的相应位置。mapFileNames[source_, filenames_, target_] :=
Module[{depth = FileNameDepth[source]}
, FileNameJoin[{target, FileNameDrop[#, depth]}]& /@ filenames
]
该函数使用
FileNameDrop
从每个文件名中删除领先的源路径元素,并使用FileNameJoin
在每个结果的前面添加目标路径。要删除的前导元素的数量是通过将FileNameDepth
应用于源路径来确定的。例如:
In[83]:= mapFileNames["/a/b", {"/a/b/x.txt", "/a/b/c/y.txt"}, "/d"]
Out[83]= {"/d/x.txt", "/d/c/y.txt"}
使用此功能,我们可以将源目录(
source
)下的HTML文件路径列表转换为目标目录(target
)下的文本文件路径列表:htmlFiles = FileNames["*.html", source, Infinity]
textFiles = StringReplace[
mapFileNames[source, htmlFiles, target]
, f__~~".html"~~EndOfString :> f~~".txt"
]
这些语句检索HTML文件列表,将它们映射到目标目录,然后将文件扩展名从
.html
更改为.txt
。现在,我们可以从生成的文本文件中提取必要的目录名称:targetDirs = DeleteDuplicates[FileNameDrop[#, -1]& /@ textFiles]
再次使用
FileNameDrop
,这一次是从每个文本文件的路径中删除文件名部分。接下来,我们需要删除目标目录(如果已经存在)并创建新的必需目录:
If[FileExistsQ[target], DeleteDirectory[target, DeleteContents -> True]]
Scan[CreateDirectory[#, CreateIntermediateDirectories -> True]&, targetDirs]
现在,我们可以执行HTML到文本的转换,这是安全的,前提是目标目录已经存在:
Scan[
Export[#[[2]], Import[#[[1]], "Plaintext"], "Text"] &
, Transpose[{htmlFiles, textFiles}]
]
关于wolfram-mathematica - 查找和转换HTML文件并在网上移动它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8138534/