【问题标题】:loop with multiple columns in shell在外壳中具有多列的循环
【发布时间】:2015-09-25 02:11:17
【问题描述】:

我有一个包含三列(ID 号、x、y)的文件

ifile.txt
1      32.2    21.4
4      33.2    43.5
5      21.3    45.6
12     22.3    32.5
32     21.5    56.3
43     33.4    23.4
44     23.3    22.3
55     22.5    32.4

我想使用 ID 号作为循环,这样读起来就像

when ID=1, then x=32.2, y=21.4
when ID=4, then x=33.2, y=43.5
and so on

我做了如下,但是看起来很漫长。

id1=1   #ID number
id2=$(wc -l < ifile.txt)   #total number of IDs
while [ $id1 -le $id2 ]
do
ID=$(awk 'NR=='$id1' {print $1}' ifile.txt)
x=$(awk 'NR=='$id1' {print $2}' ifile.txt)
y=$(awk 'NR=='$id1' {print $3}' ifile.txt)
#
#here I want to do some computation using ID, x and y
#e.g. with each ID, I will execute a program by changing its corresponding x and y values
#for instance
echo $ID $x $y
(( id1++ ))
done

我需要缩短它和一个方便的方法。

【问题讨论】:

    标签: linux shell loops unix awk


    【解决方案1】:

    这会读取每一行并对 x 和 y 进行计算(你没有说什么计算,所以我编了一个):

    $ awk '{printf "ID=%2s: x+y*y=%7.2f\n",$1,$2+$3*$3;}' ifile.txt 
    ID= 1: x+y*y= 490.16
    ID= 4: x+y*y=1925.45
    ID= 5: x+y*y=2100.66
    ID=12: x+y*y=1078.55
    ID=32: x+y*y=3191.19
    ID=43: x+y*y= 580.96
    ID=44: x+y*y= 520.59
    ID=55: x+y*y=1072.26
    

    换句话说,awk 比 shell 有更好的数学支持。如果要进行计算,请在 awk 中进行。

    【讨论】:

    • 感谢您的回答。但我需要分别使用 ID、x 和 y 值,以便在下一次计算中使用它们。这些值有几个执行。我已经相应地编辑了我的问题。
    • @Kayan 为什么你认为你不能在 awk 中进行计算?
    • @Kayan 顺便说一下,bash 只做 integer 算术。您输入的数字是浮点数。
    • 我的脚本运行良好。我可以通过使用for id in $(cat ifile.txt); do 之类的东西来使它更短...
    • Kayan:不要使用$(cat ifile.txt)。如果您必须使用 shell,请使用@JonathanLeffler 的答案中的方法,该方法显示了如何使用 shell 有效地读取文件。 (如果你想做“计算”,还有xy是浮点数,shell不能处理浮点数的问题。)
    【解决方案2】:

    表面上,你可以使用:

    while read ID x y
    do
        case "$ID" in
        …
        esac
        echo "$ID $x $y"
    done < ifile.txt
    

    case 可能是也可能不是决定在读取一行时采取什么操作的适当方法。

    我使用了read 而不使用-r,因为如果数据包含受-r 存在或不存在影响的字符(反斜杠),代码将具有heebie-jeebies。两者都不会特别可靠。你可以另外判断并使用-r,从而满足“你应该使用-r”旅。

    请注意,这会读取文件一次,而您的代码会为文件中的每一行读取文件三次。这是一个 O(N2) 算法,其中 O(N) 算法是合适的。

    如果您的计算足够复杂,您最好使用比 shell 更强大的语言。您可以考虑使用 awk 或 Perl 或 Python(或许多其他语言)。

    【讨论】:

      猜你喜欢
      • 2013-03-17
      • 1970-01-01
      • 1970-01-01
      • 2016-07-08
      • 2014-02-21
      • 1970-01-01
      • 2012-11-23
      • 2011-01-29
      • 1970-01-01
      相关资源
      最近更新 更多