1

我有一个文件目前的形式

location1 attr attr  ... attr
location2 attr attr  ... attr
...
locationn attr atrr  ... attr

我想要做的是遍历每一行,获取位置(第一个字段)然后遍历属性。到目前为止,我知道如何获取第一个字段,但不遍历属性。每行也有不同数量的属性。

TEMP_LIST=$DIR/temp.list

while read LINE
do
        x=`echo $LINE | awk '{print $1}'`
        echo $x
done<$TEMP_LIST

有人可以告诉我如何遍历属性吗?我想得到这样的效果

while read LINE
do
    location=`echo $LINES |awk '{print $1}'`
    for attribute in attributes
        do something involving the $location for the line and each individual $attribute
done<$TEMP_LIST

我目前在 ksh shell 中工作,但任何其他 unix shell 都可以,我会找出如何翻译。如果有人可以提供帮助,我真的很感激,因为这可以节省我很多时间。谢谢你。

4

3 回答 3

1

类似于 DreadPirateShawn 的解决方案,但更简单一些:

while read -r location all_attrs; do
    read -ra attrs <<< "$all_attrs"

    for attr in "${attrs[@]}"; do
        : # do something with $location and $attr
    done
done < inputfile

第二read行利用了 bash 的 herestring 特性。

于 2013-01-19T03:36:33.083 回答
0

由于您已经在发布的代码中使用了 awk,为什么不学习如何使用 awk,因为它是为此类问题而设计的。

while read LINE
do
    location=`echo $LINES |awk '{print $1}'`
    for attribute in attributes
        do something involving the $location for the line and each individual $attribute
done<$TEMP_LIST

用 awk 写成

#!/bin/bash
tempList="MyTempList.txt"

awk '{  # implied while loop for input records by default
    location=$1
    print "location=" location    # location as a "header"
    for (i=2;i<NF;i++) {
        printf("attr%d=%s\t", i, $i) # print each attr with its number
   }
   printf("\n")     # add new-line char to end of each line of attributes
}' ${tempList}

如果要保存输出,请使用awk '{.....}' ${tempList}> ${tempList}.new

awk 在读取文件时设置了许多变量。NF表示当前行的 NumberOfFields。因此,for 循环从字段 2 开始,并以提供的格式打印该行上的所有剩余字段(根据您的需要进行更改)。该i<=NF驱动器能够在一行上打印所有元素。有时你会希望第三个到最后一个元素在线,所以你可以对存储在 NF 中的值进行数学运算,比如thirdFromLast=$(NF-3). 对于所有数字变量,您可以将其作为值“取消引用”,并要求 awk 打印 $N(th) 字段中存储的值。即尝试

print "thirdFromLast="(NF-3)
print "thirdFromLast="$(NF-3)

...查看在$包含数字的变量上产生的差异。

(对于大量数据,1 个 awk 进程将比使用子进程收集部分文件的效率高得多。)

还可以按照本教程grymoire 的 awk 教程进行操作

IHTH

于 2013-01-19T01:58:48.487 回答
0

这可能也适用于其他 shell,但这里有一种适用于 Bash 的方法:

#!/bin/bash

TEMP_LIST=temp.list

while read LINE
do

    # Split line into array using space as delimiter.
    IFS=' ' read -a array <<< $LINE

    # Use first element of array as location.
    location=${array[0]}
    echo "First param: $location"

    # Remove first element from array.
    unset array[0]

    # Loop through remaining array elements.
    for i in "${array[@]}"
    do
        echo "   Value: $i"
    done

done < $TEMP_LIST
于 2013-01-19T01:28:25.040 回答