Python 从多个文件(结构输出)提取数据并打印到一个文件
请帮我从400个文件中提取值。到目前为止,我从未做过类似的事情,我不知道从哪里开始。因为我不是程序员,我不知道哪个软件程序适合使用:R、SAS、Python、命令提示符、bash、awk。在使用命令提示符bash运行某些应用程序时,我有一些使用SAS和R(大多数是带有行和列的“常规”文件)进行数据操作/管理的经验Python 从多个文件(结构输出)提取数据并打印到一个文件,python,r,bash,awk,cmd,Python,R,Bash,Awk,Cmd,请帮我从400个文件中提取值。到目前为止,我从未做过类似的事情,我不知道从哪里开始。因为我不是程序员,我不知道哪个软件程序适合使用:R、SAS、Python、命令提示符、bash、awk。在使用命令提示符bash运行某些应用程序时,我有一些使用SAS和R(大多数是带有行和列的“常规”文件)进行数据操作/管理的经验 我在云计算上运行Structure(人口遗传学软件) 输出为400个文件/次。他们的名字是:job_01_01-output_f;作业\u 01\u 02-输出\u f……作业\u 4
一个简单的Python实现。请告诉我它是否适合您
导入全局
将os.path导入为操作系统
进口稀土
导入uuid
def extract_数据(来源:str,
导出:str=None,
嵌套:bool=False,
定界:str=“,”,
摘录:str=“估计的Ln数据概率”)->无:
"""
从源中提取“数据的估计Ln概率”的值并导出
它保存在一个文本文件中。
Args:
来源:包含“job\u 01\u 01-output\u f”文件的目录。
导出:输出文件的路径。
嵌套:布尔值,如果要同时使用嵌套文件。
提取:需要提取其各自值的关键字。
"""
regex=r“^\b{}\b.+$”格式(摘录)
nest=“**”如果嵌套,则为else“*”
值=[]
对于glob.glob(f“{source}/{nest}”中的文件,recursive=True):
raw=os.basename(文件)
如果raw.startswith(“作业”)和raw.endswith(“输出”):
打开(文件“r”)作为_文件:
matches=re.finditer(regex,_file.read(),re.MULTILINE)
entry=f“{raw}{divident}{list(匹配项)[0].group().rsplit('=')[-1]}\n”
values.append(条目)
export=export-if-else-os.join(源代码,f“{str(uuid.uuid4())}.txt”)
打开(导出,“w”)为_文件时:
_file.writelines(值)
#其中“/home/SOME_USER/Downloads”是您拥有这400个文件的路径。
提取数据(“/home/SOME\u USER/Downloads”)
batch
对于您的文字问题:
(for /f "tokens=2 delims==" %%a in ('findstr /c:"Estimated Ln Prob of Data" "job_??_??-output_f"') do echo %%a)>result.csv
如果您也需要文件名:
(for /f "tokens=1,3 delims=:=" %%a in ('findstr /c:"Estimated Ln Prob of Data" "job_??_??-output_f"') do echo %%a,%%b)>result.csv
将grep与PCREs结合使用,从Dropbox链接获得正面的后视和数据:
$ grep -Pohm 1 "(?<=^Estimated Ln Prob of Data = ).*" job_*
使用的开关:
-P, --perl-regexp
Interpret PATTERNS as Perl-compatible regular expressions (PCREs).
-h, --no-filename
Suppress the prefixing of file names on output.
-o, --only-matching
Print only the matched (non-empty) parts of a matching line
-m NUM, --max-count=NUM
Stop reading a file after NUM matching lines.
另一种使用awk的方法是:
$ for f in job* ; do awk '/^Estimated Ln Prob of Data/{print $NF;exit}' $f ; done
和GNU awk:
$ awk '/^Estimated Ln Prob of Data/{print $NF;nextfile}' job_*
首先,我提供这个答案是为了提供更多的选择,我认为最好的答案是“的
grep
解决方案,因为学习熟练使用grep
将是一项特别有用的技能。如果你认为你可能会被困在Windows环境中,特别是当你身处一个最小的环境中时,这个解决方案也很方便当然有权力地狱
PowerShell中有一个选项:
Get-Content "job_01_01-output_f" | ForEach-Object { if ($_ -match "Estimated Ln Prob of Data * = * ([-.\d]+)") { $Matches[1]} }
另一个选项使用sed
:
sed-ne“s/估计的Ln数据概率*=*\([-.0-9]\+\)/\1/gp”“作业\u 01\u 01-输出\u f”
如果我正确理解了您想要的内容,那么在终端中将目录更改为文件所在的位置,然后使用以下复合命令:awk-F'=''/Estimated Ln Prob of Data/{print$2}'*>/path/to/file.csv
如果您希望您的问题提供一个简洁、可测试的文本样本输入(没有图像和链接)(例如,您提到的两个文本文件,每个文件有4行或5行文本)和预期输出(您希望根据该输入生成的CSV)然后,更多的人将愿意/能够帮助您。请参阅。谢谢@user3439894!它正在工作!在awk代码中是否可以在值旁边包含文件名,以便我可以像导入两列一样导入此文件(空格或逗号可以是分隔符)例如:job_01_01-output_f-5570597.3 job_40_01-output_f-2834943326.2是:awk-f'=''/Estimated Ln Prob of Data/{print FILENAME,,,,,$2}“*>>/path/to/file.csv
还有哦,不!RIP Eddie Van Halen.谢谢!我尝试了awk,它正在工作!在awk代码中是否可以在值旁边包含文件名,这样我可以像导入两列一样导入此文件(空格或逗号可以是分隔符)例如:job_01_01-output_f-5570597.3 job_40_01-output_f-2834943326.2当然,这里有一个内置变量FILENAME
,只需将print$NF
更改为print FILENAME,$NF
。谢谢!工作!是否可以在值旁边包含文件名,以便导入此file类似于两列(空格或逗号可以是分隔符)。例如:job_01_01-output_f-5570597.3 job_40_01-output_f-2834943326.2,添加了对分隔符的支持(默认值为逗号“,”)@BellaThanky!谢谢!我还尝试了这段代码,它分别适用于每个文件。
Get-Content "job_01_01-output_f" | ForEach-Object { if ($_ -match "Estimated Ln Prob of Data * = * ([-.\d]+)") { $Matches[1]} }