【问题标题】:pasting a value to xlsx using shell使用 shell 将值粘贴到 xlsx
【发布时间】:2018-12-17 09:10:49
【问题描述】:

我有一个 xlsx 格式的模板文件,我想将一个动态值粘贴到一个特定的单元格中,即根据程序流程,该单元格中的值将发生变化,这反过来又会改变 xlsx 文件中不同进程的条件。

我试过像

这样的代码
awk -v value=$value -v row=$row -v col=$col 'BEGIN{FS=OFS="@"} NR==row {$col=value}1' file.csv 

但问题是我不能将此代码用于 xlsx 文件格式。有什么办法可以对 xlsx 文件格式执行此操作,因为它是一个模板文件,我需要保留 xlsx 文件格式。

【问题讨论】:

  • 很好,您已经发布了您尝试过的代码,请始终尝试发布输入和预期输出示例,以便人们全面了解问题,请立即这样做。
  • 如果你想以xlsx 格式工作,你将不得不寻找比awk 更强大的工具,因为xslx 与csv 不同,它不是纯文本文件......许多编程语言有模块来操作这些文件(java,python,...)

标签: shell csv awk xlsx


【解决方案1】:

当我必须从 Windows PC 上的 Excel 工作簿中提取值时,我会安装 cygwin,然后编写一个小的 shell 脚本:

cygstart "/path/to/xls2csv.vbs" 'C:/cygwin64/path/to/bookName.xlsx'
awk 'whatever' '/path/to/bookName/sheetName.csv'

以及从工作簿中提取每个工作表作为单独的 CSV 命名的工作是通过此 Visual Basic 脚本在以工作簿命名的公共目录下以“.csv”为后缀的工作表名称命名的:

$ cat xls2csv.vbs
csv_format = 6

Dim strFilename
Dim objFSO
Set objFSO = CreateObject("scripting.filesystemobject")
strFilename = objFSO.GetAbsolutePathName(WScript.Arguments(0))
If objFSO.fileexists(strFilename) Then
  Call Writefile(strFilename)
Else
  wscript.echo "no such file!"
  wscript.echo strFilename
End If
Set objFSO = Nothing

Sub Writefile(ByVal strFilename)
Dim objExcel
Dim objWB
Dim objws

Set objExcel = CreateObject("Excel.Application")
Set objWB = objExcel.Workbooks.Open(strFilename)

For Each objws In objWB.Sheets
  objws.Copy
  objExcel.ActiveWorkbook.SaveAs objWB.Path & "\" & objws.Name & ".csv", csv_format
  objExcel.ActiveWorkbook.Close False
Next

objWB.Close False
objExcel.Quit
Set objExcel = Nothing
End Sub

如果文件名或目录名中有空格,该命令将失败,因此我们需要将其替换为下划线。实际上,我通常将 Xls 文件复制到一个临时目录,并在运行上述文件之前给它一个临时名称,这样我就可以在它上面运行上述文件,而不会影响原始文件,也不必关心原始文件的路径。它需要输入 Excel 工作簿的绝对路径。

您可能需要在awk 命令之前输入wait 和/或sleep,以确保VB 脚本在awk 命令运行之前完成。我未显示的 shell 代码对 VB 脚本创建然后删除 tmp 文件以确保 VB 脚本完成并循环尝试然后杀死 Excel 如果它在调用 awk 之前没有启动或挂起,则有点复杂的测试 - 我写了很长时间以前,它是一团糟,我怀疑它是否真的有必要或一个好的方法,这就是为什么我没有在这里包括它。

要将这些值返回到多表工作簿中,您必须使用 Excel 打开任何更新/生成的 CSV(或复制/粘贴)。可能还可以编写一些其他 VB 脚本来为您导入 CSV,就像我在上面导出它们一样,但我从来不需要那个功能,所以不知道它是什么样子的。

我不知道您是否需要它 - 如果您的 awk 脚本写入 CSV,那么您只需双击输出 .csv,Excel 就会像任何 .xls 或 .xlsx Excel 一样愉快地打开并显示它文件。

所以,做你想做的事,假设你的原始内容在单页 Excel 工作簿“MyStuff.xlsx”的“Sheet1”中,你可以从 cygwin 执行此操作:

cygstart "/path/to/xls2csv.vbs" 'C:/cygwin64/path/to/MyStuff.xlsx'
wait; sleep 10     # or similar
awk -v value="$value" -v row="$row" -v col="$col" 'BEGIN{FS=OFS=","} NR==row {$col=value}1' '/path/to/MyStuff/Sheet1.csv' > "/tmp/tmp$$" &&
mv "/tmp/tmp$$" '/path/to/MyStuff/Sheet1.csv'

然后在 Windows 中双击 /path/to/MyStuff/Sheet1.csv 以在 Excel 中打开它(您可能需要在第一次这样做时将 .csv 文件后缀与 Excel 关联)。

请注意,以上仅处理简单的 CSV,请参阅What's the most robust way to efficiently parse CSV using awk?,了解如何使用 awk 稳健地处理 CSV。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-22
    • 2016-02-29
    相关资源
    最近更新 更多