在 AWK 中打印数组中的所有元素

Posted

技术标签:

【中文标题】在 AWK 中打印数组中的所有元素【英文标题】:Print all elements in an array in AWK 【发布时间】:2021-06-06 03:44:38 【问题描述】:

我想在 awk 中遍历数组中的所有元素并打印。这些值来自以下文件:

Ala     A       Alanine
Arg     R       Arginine
Asn     N       Asparagine
Asp     D       Aspartic acid
Cys     C       Cysteine
Gln     Q       Glutamine
Glu     E       Glutamic acid
Gly     G       Glycine
His     H       Histidine
Ile     I       Isoleucine
Leu     L       Leucine
Lys     K       Lysine
Met     M       Methionine
Phe     F       Phenylalanine
Pro     P       Proline
Pyl     O       Pyrrolysine
Ser     S       Serine
Sec     U       Selenocysteine
Thr     T       Threonine
Trp     W       Tryptophan
Tyr     Y       Tyrosine
Val     V       Valine
Asx     B       Aspartic acid or Asparagine
Glx     Z       Glutamic acid or Glutamine
Xaa     X       Any amino acid
Xle     J       Leucine or Isoleucine
TERM    TERM    termination codon

我试过这个:

awk 'BEGINFS="\t";OFS="\t"if (FNR==NR) codes[$1]=$2; elsenextENDfor (key in codes);print key,codes[key],length(codes)' $input1 $input2

输出始终为Cys C 27,当我将codes[$1]=$2 替换为codes[$2]=$1 时,我得到M Met 27

如何让我的代码按顺序打印出所有值?我不明白为什么当我知道数组长度为 27 时,我的代码会选择性地只打印出一个元素。 (为了使我的代码最小化,我已经排除了 elsenext 中的代码 - 否则我只想打印数组 codes 中的所有元素,同时保留 else*** 命令)

根据How to view all the content in an awk array?,上面的语法应该可以工作。我在这里尝试过echo -e "1 2\n3 4\n5 6" | awk 'my_dict[$1] = $2;END for(key in my_dict) print key " : " my_dict[key],": "length(my_dict)',效果很好。

【问题讨论】:

您只将 1 个文件(在您最初的问题中,后来您更改为 2 个文件)传递给您的 awk,现在我可以看到您正在将 2 个文件传递给 awk 程序。如果您只是想从 1 个文件中打印数组项,能否请您告诉我?如果是这种情况,那么我们不需要使用第二个文件。 您的编辑无法解释第二个文件包含的内容。无论如何,您的代码完全忽略了第二个文件。 我想用第一个输入文件$input1来构建一个awk数组。然后我将使用数组 in 对 file2.gsub(key, codes[key], $3) 中的一个字段进行 gsub 处理。我的困惑在于数组codes,它似乎不允许我遍历它的所有 27 个元素。如果需要,我可以提供指向第二个文件/我所有 AWK 代码的链接 另外,你的代码根本不像你说的那样做。请edit提供minimal reproducible example。 您的代码采用制表符分隔的列,但您的示例数据似乎在列之间有空格。如果您真的想处理空格分隔的数据,请取出FS="\t"。 (即使那样,您的代码也只处理两列,而您的数据有三列。) 【参考方案1】:

使用您展示的示例和尝试,请尝试在 GNU awk 中遵循、编写和测试。

awk '
BEGIN
  FS=OFS="\t"


  codes[$1]=$2

END
  for(key in codes)
     print key,codes[key],length(codes)
  
' Input_file

将在几分钟内添加详细的解释和 OP 的遗漏。

说明:为上述添加详细说明。

awk '                     ##Starting awk program from here.
BEGIN                    ##Starting BEGIN section from here.
  FS=OFS="\t"             ##Setting FS and OFS as TAB here.


  codes[$1]=$2            ##Creating array codes with index of 1st field and value of 2nd field

END                      ##Starting END block of this program from here.
  for(key in codes)      ##Traversing through codes array here.
     print key,codes[key],length(codes)  ##Printing index and value of current item along with total length of codes.
  
' Input_file             ##Mentioning Input_file name here.

【讨论】:

做了一些修改。理想情况下,将给出两个输入文件。 FNR==NR时读取第一个文件失败的部分。 @Kibet,是的,我已经在您的问题下发表了评论,请提供相关信息,以便我可以尝试帮助您,谢谢。 已解决...只是; 和空格的问题 @Kibet,很高兴听到这个消息,您能否在这里发布您的答案,这将对未来的用户有所帮助,请添加答案,谢谢。 @Kibet,当然,请添加它作为答案,以便将来的用户可以受益【参考方案2】:

我有点困惑你在做什么,但是要按顺序打印代码,加上编号,(忽略名称),你可以这样做:

awk 'seq[++n]=$2; codes[$2]=$1 
    ENDfor (i=1;i<=n;i++) printf "%s\t%s\t%d\n", codes[seq[i]], seq[i], i' file

它使用两个数组来协调序列号与seq数组中的单个字母,然后是codes数组中的代码的字母。

使用/输出示例

$ awk 'seq[++n]=$2; codes[$2]=$1 
    ENDfor (i=1;i<=n;i++) printf "%s\t%s\t%d\n", codes[seq[i]], seq[i], i' file
Ala     A       1
Arg     R       2
Asn     N       3
Asp     D       4
Cys     C       5
Gln     Q       6
Glu     E       7
Gly     G       8
His     H       9
Ile     I       10
Leu     L       11
Lys     K       12
Met     M       13
Phe     F       14
Pro     P       15
Pyl     O       16
Ser     S       17
Sec     U       18
Thr     T       19
Trp     W       20
Tyr     Y       21
Val     V       22
Asx     B       23
Glx     Z       24
Xaa     X       25
Xle     J       26
TERM    TERM    27

【讨论】:

【参考方案3】:

已解决:该错误是由于在此处引入; 导致的:ENDfor (key in codes);print key,codes[key],length(codes)。 解决方案:

awk 'BEGINFS="\t";OFS="\t"if (FNR==NR) codes[$1]=$2; elsenextENDfor (key in codes)print key,codes[key],length(codes)' $input1 $input2

【讨论】:

以上是关于在 AWK 中打印数组中的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

shell数组和awk数组

打印出数组数组中元素的所有组合[重复]

寻找旋转排序数组中的最小值 II(数组二分查找)打印1000以内的所有素数,并从键盘输入一个正整数,判断是否为素数数组元素统计(算法初阶基础知识)

c ++为啥在指数时不打印所有元素

在Ruby中的同一行中打印不同大小数组的数组元素

在一行中打印十六进制数组的所有元素