首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在cygwin下使用awk从excel电子表格中打印字段?

如何在cygwin下使用awk从excel电子表格中打印字段?
EN

Stack Overflow用户
提问于 2019-06-14 05:39:55
回答 1查看 0关注 0票数 0

我们似乎看到越来越多关于在Excel电子表格上执行awk的问题,所以这里是关于如何做特定事情的Q / A.

我在Excel电子表格中有这些信息"$D/staff.xlsx""$D"我的桌面的路径在哪里):

代码语言:javascript
复制
Name   Position
Sue    Manager
Bill   Secretary
Pat    Engineer

我想打印给定名称的位置字段,例如Secretary给定输入的输出Bill

我目前可以从Excel保存为CSV以获取:

代码语言:javascript
复制
$ cat "$D/staff.csv"
Name,Position
Sue,Manager
Bill,Secretary
Pat,Engineer

然后运行:

代码语言:javascript
复制
$ awk -F, -v name="Bill" '$1==name{print $2}' "$D/staff.csv"
Secretary

但这只是一个较大任务的一小部分,因此我必须能够从shell脚本自动执行此操作,而无需手动打开Excel以导出CSV文件。如何从运行cygwin的Windows PC上做到这一点?

EN

回答 1

Stack Overflow用户

发布于 2019-06-14 15:04:36

以下VBS和shell脚本的组合为Excel电子表格中的每个工作表创建一个CSV文件:

代码语言:javascript
复制
$ 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!"
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

.

代码语言:javascript
复制
$ cat xls2csv
PATH="$HOME:$PATH"

# the original XLS input file path components
inXlsPath="$1"
inXlsDir=$(dirname "$inXlsPath")
xlsFile=$(basename "$inXlsPath")
xlsBase="${xlsFile%.*}"

# The tmp dir we'll copy the XLS to and run the tool on
# to get the CSVs generated
tmpXlsDir="/usr/tmp/${xlsBase}.$$"
tmpXlsPath="${tmpXlsDir}/${xlsFile}"
absXlsPath="C:/cygwin64/${tmpXlsPath}" # need an absolute path for VBS to work

mkdir -p "$tmpXlsDir"

trap 'rm -f "${tmpXlsDir}/${xlsFile}"; rmdir "$tmpXlsDir"; exit' 0

cp "$inXlsPath" "$tmpXlsDir"

cygstart "$HOME/xls2csv.vbs" "$absXlsPath"

printf "Waiting for \"${tmpXlsDir}/~\$${xlsFile}\" to be created:\n" >&2
while [ ! -f "${tmpXlsDir}/~\$${xlsFile}" ]
do
    # VBS is done when this tmp file is created and later removed
    printf "." >&2
    sleep 1
done
printf " Done.\n" >&2

printf "Waiting for \"${tmpXlsDir}/~\$${xlsFile}\" to be removed:\n" >&2
while [ -f "${tmpXlsDir}/~\$${xlsFile}" ]
do
    # VBS is done when this tmp file is removed
    printf "." >&2
    sleep 1
done
printf " Done.\n" >&2

numFiles=0
for file in "$tmpXlsDir"/*.csv
do
    numFiles=$(( numFiles + 1 ))
done

if (( numFiles >= 1 ))
then
    outCsvDir="${inXlsDir}/${xlsBase}.csvs"
    mkdir -p "$outCsvDir"
    mv "$tmpXlsDir"/*.csv "$outCsvDir"
fi

现在我们执行shell脚本,在内部调用cygstart来运行VBS脚本以生成CSV文件(每张一个)在Excel文件所在的同一目录下的子目录中,该目录基于Excel文件名命名(例如Excel文件staff.xlsx生成CSV目录staff.csvs):

代码语言:javascript
复制
$ ./xls2csv "$D/staff.xlsx"
Waiting for "/usr/tmp/staff.2700/~$staff.xlsx" to be created:
.. Done.
Waiting for "/usr/tmp/staff.2700/~$staff.xlsx" to be removed:
. Done.

Sheet1目标Excel文件中只有一个具有默认名称的工作表,"$D/staff.xlsx"因此上面的输出是一个文件"$D/staff.csvs/Sheet1.csv"

代码语言:javascript
复制
$ cat "$D/staff.csvs/Sheet1.csv"
Name,Position
Sue,Manager
Bill,Secretary
Pat,Engineer

$ awk -F, -v name="Bill" '$1==name{print $2}' "$D/staff.csvs/Sheet1.csv"
Secretary

另请参阅使用awk有效解析CSV的最有效方法是什么?然后,如何操作这些CSV。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/-100007018

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档