获取列名 + 迭代 + 排序 + awk



这是我的文件

$ cat -v test6 | head
"Rec_Open_Date"|"MSISDN"|"IMEI"|"Data_Volume_Bytes"|"Device_Manufacturer"|"Device_Model"|"Product_Description"|"Data_Volume_MB"|">20MB/30"|">200MB/30"|">2048MB/30"|">5120MB/30"|">10240MB/30"
"2015-10-06"|"427"|"060"|"137765"|"Samsung Korea"|"Samsung SM-G900I"|"$39 Plan"|"0.131383"|"0"|"0"|"0"|"0"|"0"
"2015-10-06"|"592"|"620"|"0"|"Apple Inc"|"Apple iPhone 6 (A1586)"|"PREPAY  STD - TRIAL - #16"|"0"|"0"|"0"|"0"|"0"|"0"
"2015-10-06"|"007"|"290"|"0"|"Apple Inc"|"Apple iPhone 6 (A1586)"|"PREPAY PLUS - $0 -"|"0"|"0"|"0"|"0"|"0"|"0"
"2015-10-06"|"592"|"050"|"48836832"|"Apple Inc"|"Apple iPhone 5S (A1530)"|"Talk and Text Connect Flexi Plan"|"46.5744"|"1"|"1"|"0"|"0"|"0"
"2015-10-06"|"409"|"720"|"113755347"|"Samsung Korea"|"Samsung SM-G360G"|"$29 CARRYOVER PLAN"|"108.486"|"1"|"1"|"1"|"0"|"0"
"2015-10-06"|"742"|"620"|"19840943"|"Apple Inc"|"Apple iPhone S (A1530)"|"PREPAY STD - $0 - #2"|"18.9218"|"1"|"1"|"0"|"0"|"0"
"2015-10-06"|"387"|"180"|"0"|"HUAWEI Technologies Co Ltd"|"HUAWEI HUAWEI G526-L11"|"PREPAY STD - $1 - #4"|"0"|"0"|"0"|"0"|"0"|"0"
"2015-10-06"|"731"|"570"|"2258243"|"Samsung Korea"|"Samsung SM-N910U"|"Business Freedom"|"2.15363"|"1"|"0"|"0"|"0"|"0"
"2015-10-06"|"556"|"910"|"13332272"|"Samsung Korea"|"Samsung GT-I9505"|"$49 Plan"|"12.7146"|"1"|"1"|"0"|"0"|"0"

我对列名称 9-13 感兴趣

$ head -n1 test6 | tr '|' 'n' | cat -n
     1  "Rec_Open_Date"
     2  "MSISDN"
     3  "IMEI"
     4  "Data_Volume_Bytes"
     5  "Device_Manufacturer"
     6  "Device_Model"
     7  "Product_Description"
     8  "Data_Volume_MB"
     9  ">20MB/30"
    10  ">200MB/30"
    11  ">2048MB/30"
    12  ">5120MB/30"
    13  ">10240MB/30"

我想使用 awk 来获取名称,但我想控制顺序。这有效,但排序不像我想要的那样:

$ awk -F'|' -v q='"' 'NR==1{for (i=9;i<=NF;i++) col[i]=$i}; END { for (i in col) print col[i]}' test6;
">200MB/30"
">2048MB/30"
">5120MB/30"
">10240MB/30"
">20MB/30"
$

我希望排序从上到下和/或颠倒,即 9-13 或 13-9。为了清楚起见,我在输出中保留了数字(9-13),我不希望它们出现在我的输出中。我希望我的输出像我上面的 awk 输出一样。这可以在awk中完成还是我必须使用其他东西?

9  ">20MB/30"
10  ">200MB/30"
11  ">2048MB/30"
12  ">5120MB/30"
13  ">10240MB/30"

这就是我想要的和/或相反,我希望它可以从 awk 中完成。

">20MB/30"
">200MB/30"
">2048MB/30"
">5120MB/30"
">10240MB/30"

编辑1 我从下面的答案中回答

关键是这个for (i = 9; i <= NF; i++) print col[i] v 这个for (i in col) print col[i]

$ awk -F'|' -v q='"' 'NR==1{for (i=9;i<=NF;i++) col[i]=$i}; END { for (i = NF; i >= 9; i--) print col[i]}' test6
">10240MB/30"
">5120MB/30"
">2048MB/30"
">200MB/30"
">20MB/30"
$ awk -F'|' -v q='"' 'NR==1{for (i=9;i<=NF;i++) col[i]=$i}; END { for (i = 9; i <= NF; i++) print col[i]}' test6
">20MB/30"
">200MB/30"
">2048MB/30"
">5120MB/30"
">10240MB/30"

您的代码无法可靠地工作,因为awk数组是关联的,并且扫描数组的顺序取决于实现。 GNU awk可以在一定程度上控制扫描顺序。但是,由于您知道索引,因此您可以按照 Michael 的建议轻松直接使用它们:

awk -F'|' -v q='"' 'NR==1{for (i=9;i<=NF;i++) col[i]=$i}; END { for (i = 9; i <= 13; i++) print col[i]}' test6

请查看以下内容是否符合您的需求:

awk -F'|' -v q='"' '{if(FNR==1){for (i=0;i<=NF;i++) print $i;}}' test6

短管道可以做到这一点:

head -1 input | cut -f9-13 -d'|' | tr '|' 'n'

">20MB/30"
">200MB/30"
">2048MB/30"
">5120MB/30"
">10240MB/30"

但这假设引号内没有管道符号

以及使用具有相同假设的awk的版本:

awk -vFPAT='[^"|]+' 'NR==1{for(i=9;i<=13;i++){print $i}}' input

这给出了

>20MB/30
>200MB/30
>2048MB/30
>5120MB/30
>10240MB/30

相关内容

  • 没有找到相关文章

最新更新