python - 通过 python 运行 shell 命令来连接 Windows 机器中的多个 CSV 文件
问题描述
目标:在特定条件下连接多个 CSV 文件。
- 条件:Windows 10 机器 + 任何 shell 命令(例如,
awk
)+ Python <= 3.7。 - 免责声明:我知道有很多方法可以做到这一点,包括:使用 pandas 数据帧连接;或使用 python 的
shutil
; 或者在 shell 上直接使用系统命令(例如,awk
)而不使用 python。但同样,我想要一个完全符合上述条件的答案。
这是我当前正在尝试运行的 shell 命令示例(如果我直接在 shell 上运行,则可以使用)
$ awk "(NR == 1) || (FNR > 1)" "..\\results\\raw*.csv" > "..\\results\\consolidated.csv"
这就是我通过python运行它的方式subprocess
:
src_files = os.path.join('..', 'results', 'raw*.csv')
dest_file = os.path.join('..', 'results', 'consolidated.csv')
result = subprocess.run('awk "(NR == 1) || (FNR > 1)" "{}" > "{}"'.format(src_files, dest_file),
shell=True,
capture_output=True)
但是,我不断收到以下错误:
print(result.stderr)
b"awk: fatal: cannot open file `..\\results\\raw*.csv' for reading (No such file or directory)\n"
我应该指出,如果我在 Unix 机器上运行这个 python 代码,它就可以工作(如果格式周围的引号{}
被删除)。python 代码不能在 Windows 机器上运行。
因此,我相信这可能与正确转义命令字符串有关,因为当我指定某些文件的名称时,此命令有效。尽管如此,我还是无法找到逃避*
符号并完成所有这些工作的正确方法。
PS:为工作示例生成数据
for i in range(1, 4):
pd.DataFrame([[i*1, i*2, i*3]], columns=['a', 'b', 'c']).to_csv(os.path.join('results', 'raw-{}.csv'.format(i)), index=False, sep=';')
PS2:使用的文件夹结构
|-- script_folder/
| |-- consolidation_script.py
|-- results/
| |-- raw-1.csv
| |-- raw-2.csv
| |-- raw-3.csv
解决方案
考虑cwd
在找到当前脚本路径后使用参数更改工作目录。是的,os.path.dirname()
被调用两次以获取当前目录的父级。
import os, subprocess
# RETRIEVE CURRENT DIRECTORY OF SCRIPT
cd = os.path.dirname(os.path.abspath(__file__))
arglist = ["awk", "(NR == 1) || (FNR > 1)", "raw*.csv", ">", "consolidated.csv"]
result = subprocess.run(arglist,
cwd = os.path.join(os.path.dirname(cd), 'results'),
shell=True,
capture_output=True)
推荐阅读
- regex - 在字符串中搜索某些单词
- c# - 将异常消息从服务传播到控制器 .NET
- java - 编写一种方法来跳过输入文件中的空格 - Java
- excel - 我正在尝试导入数据以从 Excel 访问并不断被告知它无法将所有数据附加到表中
- c++ - char 和 char* 的区别
- jenkins - 如何使用新的托管 Maven settings.xml 文件更新现有的 Jenkins 作业?
- java - 在 SQLite 数据库中搜索和显示条目
- r - 在向量上使用 R 的胶水进行字符串插值,无需多次调用它
- c# - c# FluentFTP,只下载给定路径中的最后一个文件夹
- node.js - 是否可以手动将会话数据添加到 ASPStateTempSessions?我们想从 Node 应用程序中编写会话变量