簡體   English   中英

如何在shell腳本中僅打印結構化文件的一個字段?

[英]How to print just one field of a structured file in shell script?

我正在嘗試編寫一個 shell 腳本,我需要在其中以這種方式顯示汽車及其特性:

Car: Chevrolet Chevelle Malibu
MPG: 18.0
Cylinders: 8
...

我的文件是這樣的:

Car;MPG;Cylinders;Displacement;Horsepower;Weight;Acceleration;Model;Origin

    Chevrolet Chevelle Malibu;18.0;8;307.0;130.0;3504.;12.0;70;US
    Buick Skylark 320;15.0;8;350.0;165.0;3693.;11.5;70;US
    Plymouth Satellite;18.0;8;318.0;150.0;3436.;11.0;70;US
    AMC Rebel SST;16.0;8;304.0;150.0;3433.;12.0;70;US
    Ford Torino;17.0;8;302.0;140.0;3449.;10.5;70;US
    Ford Galaxie 500;15.0;8;429.0;198.0;4341.;10.0;70;US
    Chevrolet Impala;14.0;8;454.0;220.0;4354.;9.0;70;US

我試過這樣做

#! /bin/bash
i=1
line=`wc -l < cars2.csv`
while [ $i -le $line ]
do
    name=`head -$i cars2.csv | tail -1 | cut -d: -f1`
    mpg=`head -$i cars2.csv | tail -1 | cut -d: -f2`
    echo "Name: $name"
    echo "MPG: $mpg "

let i=i+1
done

我剛剛完成了這項工作,但它並沒有按照我想要的方式工作,對於每個回聲,它都會像這樣打印整行:

Name: Chevrolet Chevelle Malibu;18.0;8;307.0;130.0;3504.;12.0;70;US

MPG: Chevrolet Chevelle Malibu;18.0;8;307.0;130.0;3504.;12.0;70;US

這可以用awk相對容易地完成:

 awk -F";" 'NR==1{for(i=1;i<=NF;++i){header[i]=$i}}NR>1{for(i=1;i<=NF;++i){print header[i]": "$i}}' yourfile.txt

awk 逐行處理文件。

此 awk 腳本執行以下步驟:

  1. 告訴 awk 分號分隔一行中的每個字段-F";"
  2. 如果這是文件的第一行,則循環遍歷每個字段並將值捕獲到關聯數組,其中鍵是字段編號,值是字段值: NR==1{for(i=1;i<=NF;++i){header[i]=$i}}
  3. 如果我們經過第 1 行,則循環遍歷每個字段並打印出步驟 2 中捕獲的數組中的標頭值以及當前行的字段值: NR>1{for(i=1;i<=NF;++i){print header[i]": "$i}}

Car: Chevrolet Chevelle Malibu
MPG: 18.0
Cylinders: 8
Displacement: 307.0
Horsepower: 130.0
Weight: 3504.
Acceleration: 12.0
Model: 70
Origin: US
Car: Buick Skylark 320
MPG: 15.0
Cylinders: 8
Displacement: 350.0
Horsepower: 165.0
Weight: 3693.
Acceleration: 11.5
...

這個問題最好用awk解決。 如果你打算在 shell 中使用 while/read 循環,你需要類似的東西;

{ 
    read header # Discard the first line
    while IFS=\; read car mpg cyl disp horse weight acc model origin; do 
        echo "Car: $car"
        echo "MPG: $mpg"
        echo "Cylinders: $cyl"
    done
} < input

例如:

如果您需要按汽車名稱對其進行排序,請首先使用sort(1)對記錄進行sort(1) ,並在您使用它時去除前導空格。

# sort records (excluding header), by field 1
{ sed 1q cars2.csv
sed '1,2d; s/^[[:space:]]*//' cars2.csv |
sort -t \; -k1,1; } |

awk -F \; '
FNR==1 {
    for (i=1; i<NF; i++) {
        keys[i] = $i
    }
}
FNR!=1 {
    for (i=1; i<NF; i++) {
        print keys[i]": "$i
    }
}'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM