gpt4 book ai didi

awk - 从制表符分隔的文件中提取列

转载 作者:行者123 更新时间:2023-12-02 03:15:52 38 4
gpt4 key购买 nike

我有一个文件 (data.rdb),格式如下:

col1    col2    col3    col4    col5    col6    col7
aaa1 bbb1 ccc1 ddd1 eee1 fff1 ggg1
aaa2 bbb2 ccc2 ddd2 eee2 fff2 ggg2
aaa3 bbb3 ccc3 ddd3 eee3 fff3 ggg3

数据的一些属性:

  • 所有列均以制表符分隔
  • 列的宽度不同
  • 单元格的长度可能不同
  • 该文件将包含比显示的更多的列和几百行
  • 我提供的列名称只是通用名称,真实名称可以是任何单词,没有制表符、空格或特殊字符。

我需要使用 bash 按名称提取一些列,例如 col1col3col6,其中要选择的列来自定义为 COLUMN_LIST=$@ 的 shell 变量,其中 $@ 是传递给我的 shell 脚本的参数。每次调用脚本时,参数的数量和名称可能会发生变化。

脚本需要在bash中,不能是python或类似的。

有什么想法吗?我考虑过使用awk/gawk,但我不知道如何按列名进行选择。列顺序可能因文件而异。

谢谢豪尔赫

更新

出于某种原因,这些解决方案似乎都不适用于我的真实数据文件(即,我根本没有输出),因此我发布了其中一个的子集:

date    star    jdb texp
2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 HD217987 2400000.23551544 900.
2013-11-22 TOI-134 2400000.23551544 900.
2013-11-22 tauCet 2400000.23551544 60.
2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300.

在这种情况下,我会对 star jdbtexp 列感兴趣

更新 2

我使用了@EdMorton 的代码,结果如下:

date    star    jdb texp    date    star    jdb texp
2013-11-22 epsInd 2400000.23551544 100. 2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 epsInd 2400000.23551544 100. 2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 epsInd 2400000.23551544 100. 2013-11-22 epsInd 2400000.23551544 100.
2013-11-22 HD217987 2400000.23551544 900. 2013-11-22 HD217987 2400000.23551544 900.
2013-11-22 TOI-134 2400000.23551544 900. 2013-11-22 TOI-134 2400000.23551544 900.
2013-11-22 tauCet 2400000.23551544 60. 2013-11-22 tauCet 2400000.23551544 60.
2013-11-22 BD+01316 2400000.23551544 300. 2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300. 2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300. 2013-11-22 BD+01316 2400000.23551544 300.
2013-11-22 BD+01316 2400000.23551544 300. 2013-11-22 BD+01316 2400000.23551544 300.

更新 3

我最终使用了 EdMorton 的 awk 版本——主要是为了输出的灵 active ——但我不想让它输出错误的列的修改:

BEGIN {
numCols = split(column_list,cols)
OFS="\t"
}
{ sub(/\r$/,"") }
NR==1 {
for (fldNr=1; fldNr<=NF; fldNr++) {
f[$fldNr] = fldNr
}
}
{
for (colNr=1; colNr<=numCols; colNr++) {
colName = cols[colNr]
colVal = (colName in f ? $(f[colName]) : "")
printf "%s%s", colVal, (colNr<numCols ? OFS : ORS)
}
}

我遇到的主要问题是标题行不是制表符分隔的,因此列分割不起作用。识别制表符/非制表符的简单方法:

tr $'\t' '#' < data.rdb | head -2

它给出了我的一个测试文件:

date    star    jdb texp
2013-11-22#epsInd#2400000.23551544#100.

最佳答案

The column order might change from file to file.

您可以使用 awk 使用这种方法,它将空格分隔的标题列名称作为输入,并首先通过处理第一条记录将其转换为列号。一旦检索到所需的列号,我们就从下一行开始打印它们。

awk -v cols='col1 col3 col6' 'BEGIN {
FS=OFS="\t"
n = split(cols, a, " ")
for (i=1; i <= n; i++)
c[a[i]]
}
{
sub(/\r$/, "")
}
NR == 1 {
for (i=1; i<=NF; i++)
if ($i in c)
hdr[i]
}
{
for (i=1; i<=NF; i++)
if (i in hdr)
s = sprintf(s "%s%s", OFS, $i)
sub(OFS, "", s)
print s
s =""
} ' file | column -t

star      jdb               texp
epsInd 2400000.23551544 100.
epsInd 2400000.23551544 100.
epsInd 2400000.23551544 100.
HD217987 2400000.23551544 900.
TOI-134 2400000.23551544 900.
tauCet 2400000.23551544 60.
BD+01316 2400000.23551544 300.
BD+01316 2400000.23551544 300.
BD+01316 2400000.23551544 300.
BD+01316 2400000.23551544 300.

PS:添加了 column -t 以表格格式输出。

关于awk - 从制表符分隔的文件中提取列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56132249/

38 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com