【问题标题】:How to print variable value using awk? (code prints variable name instead)如何使用 awk 打印变量值? (代码改为打印变量名)
【发布时间】:2018-08-16 18:11:20
【问题描述】:

由于我是编写 shell 脚本的新手,请多多包涵。

输入

元数据

第 1 列 A01 A02 A03

第 2 列 A_1 A2 A_3 ...

FILENAME(当前格式示例) (2 列名称 Well 和 Area)

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62577.5

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62688.4

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62263.3

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 59554

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 54602.8

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 528.125

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62751.8

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 56752.3

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 51428.8

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 65778

Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 533.406

Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 3839.47

Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 8801.2

Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 35468.9

Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 528.125

目标是 grep 查找包含元数据中第一列字符串的行(例如 A01),并在行尾添加一个包含第二列字符串的新列(例如 A_1)

那些包含 A02 的行,得到一个带有 A_2 的新列 那些包含 A03 的行,得到一个带有 A_3 的新列,等等

我有这个脚本,它完成了大部分工作:

#!/bin/bash -l

pop=$1 ### Metadata file 

n=$(wc -l ${pop} | awk '{print $1}')

x=1
while [ $x -le $n ] 
do

        string="sed -n ${x}p ${pop}"
        str=$($string)

                var=$(echo $str | awk '{print $1, $2}')
                set -- $var
               c1=$1   ### e.g. A01 ###
               c2=$2   ### e.g. A_1 ###


                grep ${c1} FILENAME | xargs -d "\n" -rI % echo '% $c2' > ${c1}.data

        x=$(( $x + 1 ))

done

当前输出给出:

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62577.5 $c2

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62688.4 $c2

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3 $c2

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 59593.6 $c2

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 66253.3 $c2

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 59276.8 $c2

问题在于这会在末尾打印 $c2 而不是 A_1。

因此,所需的输出将是:

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62577.5 A_1

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62688.4 A_1

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3 A_1

Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 59593.6 A_1

我认为我只是在 echo '% $c2' 处使用了不正确的语法,但诸如 ${c2} 或 $2 之类的变体只有相同的问题。我在网上查看过,但目前不确定如何要求正确的语法。由于此文件有数千行,因此无法手动执行。

非常感谢任何帮助

谢谢

L

【问题讨论】:

标签: bash shell unix awk


【解决方案1】:
grep ${c1} FILENAME | xargs -d "\n" -rI % echo '% $c2' > ${c1}.data

问题在于这会在末尾打印 $c2 而不是 A_1。

变量需要用双引号来展开,比如echo "% $c2"

【讨论】:

  • 非常感谢,遗憾的是我知道这是一个简单的解决方法,但很沮丧,因为我完全不知道它是什么
【解决方案2】:

你的问题不清楚,但这就是你想做的全部吗?

$ cat file
Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3
Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62263.3
Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 3839.47

$ awk -F'_' '{print $0, gensub(/0/,"_",1,$2)}' file
Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3 A_1
Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62263.3 A_2
Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 3839.47 A_3

上面的 gensub() 使用 GNU awk,但使用任何 awk:

$ awk -F'_' '{new=$2; sub(/0/,"_",new); print $0, new}' file
Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3 A_1
Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62263.3 A_2
Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 3839.47 A_3

或者,也许您需要那个“元”文件来提供映射到不像 A02 -> A_2 那样直接和可计算的东西,然后就是这样,再次使用任何 awk:

$ cat meta
A01 whatever
A02 other_stuff
A03 somethin

$ awk 'NR==FNR{map[$1]=$2;next} {print $0, map[$2]}' meta FS='_' file
Met-test8A-DBMCK_A01_w1D27B99D4-0BA0-4AA0-B10A-04558144C3BE 62733.3 whatever
Met-test8A-DBMCK_A02_w192E97024-E632-4D00-A525-A4204DEF9ECE 62263.3 other_stuff
Met-test8A-DBMCK_A03_w175F73215-12C2-4E07-8894-795CB8F31A4D 3839.47 somethin

如果不是这些,那么请告诉我们您正在尝试做什么,这样我们可以帮助您以正确的方式做事,而不是用创可贴来做错事。

【讨论】:

  • 您好,感谢您的意见,上面的 Grisha Levit 回答得很好。但是您非常正确地表明有一种更有效的方法可以做到这一点。元文件是我熟悉的唯一方式。我会牢记这一点,并会在将来尝试使我的问题更加清晰。再次感谢
  • “很好”是相对的:-)。您的原始脚本有几个问题,而不仅仅是效率问题,因此根据您提供的输入,让它的那部分产生您期望的输出并不是那么有用(它会在给定不同输入的情况下产生意外的输出)。你说你才刚刚开始学习 shell 编程,所以只要学习以正确的方式做事,而不是一瘸一拐地希望以错误的方式做事最好。以错误的方式做这件事并没有任何好处。
  • 明白。再次感谢
猜你喜欢
  • 2018-10-25
  • 1970-01-01
  • 2010-12-22
  • 2014-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-30
相关资源
最近更新 更多