【问题标题】:How to parse only selected column values using awk如何使用 awk 仅解析选定的列值
【发布时间】:2015-01-16 16:25:21
【问题描述】:

我有一个包含以下块的示例平面文件

test my array which array is better array huh got it?

INDIA USA SA NZ AUS ARG ARM ARZ GER BRA SPN

我还有一个这样定义的数组(ksh_arr2)

ksh_arr2=$(awk '{if(NR==1){for(i=1;i<=NF;i++){if($i~/^arr/){print i}}}}' testUnix.txt)

并包含以下整数

3 5 8

现在我只想解析位于相应编号位置的列值,即第三第五和第八。 我还想要病房第二行的输出。 所以我尝试了以下

awk '{for(i=1;i<=NF;i++){if(NR >=1 && i=${ksh_arr2[i]}) do print$i ; done}}' testUnix.txt 

但它显然没有打印所需的输出。 我错过了什么?请帮忙。

【问题讨论】:

  • 首先:在 IF 子句中,您为 i 变量赋值。
  • 我正在与数组索引值进行比较.. 对吗??
  • 第二个:ksh_arr2数组是在哪里定义的?
  • 没有。 awk 中的比较运算符和赋值运算符不同。阅读this link
  • awk 程序的任何 shell 数组都是未知的。您必须使用 -v 选项,正如 Jidder 和 John1024 在他们的解决方案中使用的那样。

标签: arrays unix awk


【解决方案1】:

我将如何处理它

awk -vA="${ksh_arr2[*]}" 'BEGIN{split(A,B," ")}{for(i in B)print $B[i]}' file

说明

 -vA="${ksh_arr2[*]}"     -    Set variable A to expanded ksh array

  'BEGIN{split(A,B," ")   -    Splits the expanded array on spaces
                               (effictively recreating it in awk)

  {for(i in B)print $B[i]} -  Index in the new array print the field that is the number 
                              contained in that index

编辑

如果您想在打印时保留字段的顺序,那么这样会更好

awk -vA="${ksh_arr2[*]}" 'BEGIN{split(A,B," ")}{while(++i<=length(B))print $B[i]}' file

【讨论】:

  • 我认为您的意思可能是* 而不是@:当我测试它时,A="${ksh_arr2[@]}" 扩展为多个字符串并且没有正确分配。
  • @John1024 哦,是的,没有意识到这会是个问题。谢谢:)
  • @John1024 我也意识到我的答案(和编辑)是在你之后发布的,并且看起来我只是复制了你的答案,因为它们看起来非常相似,我只想指出情况并非如此,当您发布您的内容时,我正在创建(和编辑)。伟大的思想都一样:)
  • 是的,这可能会发生。问候
  • @Jidder 我试过 ..awk -vK="${ksh_arr2[*]}" 'BEGIN{split(K,b," ");}{for(i in b)print $ b[i]}' testUnix.txt ,现在它说 awk: String 3 cannot contain a newline character。请解释一下。
【解决方案2】:

由于没有显示示例输出,我不知道这个输出是否是你想要的。它是从提供的代码中获得的输出,只需对其进行最少的更改即可运行:

$ awk -v k='3 5 8' 'BEGIN{split(k,a," ");} {for(i=1;i<=length(a);i++){print $a[i]}}' testUnix.txt 
array
array
array



SA
AUS
ARZ

上面的代码以变量k提供的相同顺序打印出选定的列。

注意事项

  • awk 代码从未定义过 ksh_arr2。我假设这个数组的值是从 shell 传入的。此处使用-v 选项将变量k 设置为ksh_arr2 的值。

  • 无法直接将数组传入awk。可以像上面一样传入一个字符串,然后使用split 函数将其转换为数组。上面的字符串k被转换为awk数组a

  • awk 语法不同于 shell 语法。例如,awk 不使用dodone

详情

  • -v k='3 5 8'

    这定义了一个awk 变量k。要以编程方式执行此操作,请将 3 5 8 替换为 shell 中的字符串或数组。

  • BEGIN{split(k,a," ");}

    这会将变量k 中的空格分隔值转换为名为@9​​87654344@ 的数组。

  • for(i=1;i&lt;=length(a);i++){print $a[i]}

    这会按顺序打印出数组a 中的每一列。

备用输出

如果您想将每一行的输出保留在一行中:

$ awk -v k='3 5 8' 'BEGIN{split(k,a," ");} {for(i=1;i<length(a);i++) printf "%s ",$a[i]; print $a[length(a)]}' testUnix.txt 
array array array

SA AUS ARZ

【讨论】:

  • 您可能想打印$a[i] 而不是i,因为那只是1-N
  • 这不会打印第 3 5 和第 8 列的值 :(
  • @Jidder 谢谢。答案已更新:这应该可以解决列问题。
【解决方案3】:

awk 'NR&gt;=1 { print $3 " " $5 " " $8 }' testUnix.txt

【讨论】:

    猜你喜欢
    • 2021-08-01
    • 2018-04-13
    • 2012-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-05
    • 1970-01-01
    相关资源
    最近更新 更多