1

我正在浏览并从文件中读取行。他们有大量不必要的信息,我想重新格式化这些行以供以后使用,以便以后可以使用必要的信息。

文件中的示例行 (file1)

Name: *name* Date: *date* Age: *age* Gender: *gender* Score: *score*

假设我只想从文件中提取性别和年龄并稍后使用

新队

*gender*, *age*

在 bash 中:

    while read line; do
       <store variable for gender>
       <store variable for age>
     <overwrite each line in CSV - gender,age>
     <use gender/age as inputs for later comparisons>  
     done < file1

编辑:条目中没有稳定性。可以使用 a 找到一个值,然后echo $line | cut使用 a 找到另一个值,[ $line =~ "keyValue" ]然后设置该值

我正在考虑这样存储两个变量的组合:

newLine="$val1,$val2"

然后使用 sed 内联替换来$line替换$newLine.

不过,有没有更好的方法?它可能归结为变量的 sed 格式问题。

4

2 回答 2

2

您的示例为解释留下了空间,因此我假设字段值中可能有空格,但字段值中没有冒号,并且每个字段键后跟一个冒号。我还假设订单是稳定的。

while IFS=: read _ _ _ age gender _; do
    age="${age% Gender}" # Use parameter expansion to strip off the key for the *next* field.
    gender="${gender% Score}"
    printf '"%s","%s"\n' "$gender" "$age"
done < file1 > file1.csv

更新

由于您的问题现在表明没有稳定性,因此您必须遍历可能的值以获得输出:

while IFS=: read -a line; do
    unset age key sex
    for chunk in "${line[@]}"; do
        val="${chunk% *}" # Everything but the key
        case "$key" in
            Age) age="$val";;
            Gender) sex="$val";;
        esac
        # The key is for the *next* iteration.
        key="${chunk##* }"
    done
    if [[ $age || $sex ]]; then
        printf '"%s","%s"\n' "$sex" "$age"
    fi
done < file1 > file1.csv

(此外,我在 csv 中的输出值周围添加了引号,以符合实际的 csv 格式,以防性别或年龄恰好有逗号。也许有人已经 1,000,000 岁。;)

于 2013-09-21T22:10:06.103 回答
2

这将从您发布的示例输入中产生您想要的输出:

$ cat file
Name: *name* Date: *date* Age: *age* Gender: *gender* Score: *score*

$ awk -F'[: ]+' -v OFS=', ' '{for (i=1;i<NF;i+=2) a[$i]=$(i+1); print a["Gender"], a["Age"]}' file
*gender*, *age*

$ awk -F'[: ]+' -v OFS=', ' '{for (i=1;i<NF;i+=2) a[$i]=$(i+1); print a["Score"], a["Name"], a["Date"] }' file
*score*, *name*, *date*

您可以在上面看到以您喜欢的任何顺序打印您喜欢的任何字段是多么容易。

如果这不是您想要的,请发布一些更具代表性的输入。

于 2013-09-22T14:47:10.497 回答