使用shell

时间:2018-12-17 09:10:49

标签: shell csv awk xlsx

我有一个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文件格式。

1 个答案:

答案 0 :(得分:0)

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

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

通过以下可视化基本脚本完成将工作簿中的每张工作表提取为单独的CSV文件的工作,该工作簿是在工作簿命名的公用目录下基于工作表名后缀“ .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工作簿的绝对路径。

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

要将这些值返回到多页工作簿中,您必须使用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,有关一般如何使用awk可靠地处理CSV的信息,请参见What's the most robust way to efficiently parse CSV using awk?