pro*_*ian 6 wolfram-mathematica
我正在使用Mathematica处理大量的网站文件,我已将其镜像到我自己的系统上.它们分布在数百个目录中,有大量的子目录.例如,我有:
/users/me/test/directory1
/users/me/test/directory1/subdirectory2 [times a hundred]
/users/me/test/directory2
/users/me/test/directory2/subdirectory5 [etc. etc.]
Run Code Online (Sandbox Code Playgroud)
我需要做的是进入每个目录,将Import[]
所有HTML文件作为纯文本,然后将它们放在我的系统上以"directory1"命名的其他目录中.到目前为止,通过Do[]
循环,我已经能够做一个粗略的版本:然而,我现在最好的情况是将".txt"文件转储到原始目录中,这不是一个理想的解决方案,因为它们仍然是遍布我的系统.
要查找我的文件,我使用 directoryfiles = FileNames["*.htm*", {"*"}, Infinity];
一些额外的烦恼问题:
(1)重复:Mathematica是否有办法处理重复项 - 即如果我们遇到另一个index_en.html,它是否可以重命名为index_en_1.html?
(2)目录:因为所有的目录,除非我用数学来不断地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}];
Run Code Online (Sandbox Code Playgroud)
从我的角度来看,它有什么问题?除了凌乱,这是我的解决方法:我宁愿将所有文件分开而不是一个大文件 - 即将每个导入和导出作为单独的文件,但在名为'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}]
]
]
Run Code Online (Sandbox Code Playgroud)
使用示例(警告:首先删除目标目录!):
htmlTreeToPlainText["/users/me/web", "/users/me/desktop/bucket"]
Run Code Online (Sandbox Code Playgroud)
这个怎么运作
FileName...
在这种情况下,各种Mathematica 函数都很有用.首先,我们首先定义一个辅助函数mapFileNames
,它接受一个源目录,一个位于源目录中的文件名列表,以及一个目标目录.它返回一个文件路径列表,用于命名目标目录下的相应位置.
mapFileNames[source_, filenames_, target_] :=
Module[{depth = FileNameDepth[source]}
, FileNameJoin[{target, FileNameDrop[#, depth]}]& /@ filenames
]
Run Code Online (Sandbox Code Playgroud)
该函数用于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"}
Run Code Online (Sandbox Code Playgroud)
使用此函数,我们可以将源目录(source
)下的HTML文件路径列表转换为目标目录(target
)下的相应文本文件路径列表:
htmlFiles = FileNames["*.html", source, Infinity]
textFiles = StringReplace[
mapFileNames[source, htmlFiles, target]
, f__~~".html"~~EndOfString :> f~~".txt"
]
Run Code Online (Sandbox Code Playgroud)
这些语句检索HTML文件列表,将它们映射到目标目录,然后将文件扩展名从更改.html
为.txt
.我们现在可以从生成的文本文件中提取必要的目录名称:
targetDirs = DeleteDuplicates[FileNameDrop[#, -1]& /@ textFiles]
Run Code Online (Sandbox Code Playgroud)
再次FileNameDrop
使用,这次是从每个文本文件的路径中删除文件名部分.
接下来,我们需要删除目标目录(如果它已经存在)并创建新的必需目录:
If[FileExistsQ[target], DeleteDirectory[target, DeleteContents -> True]]
Scan[CreateDirectory[#, CreateIntermediateDirectories -> True]&, targetDirs]
Run Code Online (Sandbox Code Playgroud)
我们现在可以执行HTML到文本的转换,在知道目标目录已经存在的情况下是安全的:
Scan[
Export[#[[2]], Import[#[[1]], "Plaintext"], "Text"] &
, Transpose[{htmlFiles, textFiles}]
]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
219 次 |
最近记录: |