これをどのように単純化できますか?

これをどのように単純化できますか?

このスクリプトを簡素化するのに役立ちますか?

これはうまくいきますが、より簡単な方法があると思いますが、見つかりません。

文書:

Car Brand:Mercedes | Country:Germany | Car Model:300 SL | Year:04-1960
Car Brand:Lamborghini | Country:Italy | Car Model:Miura | Year:10-1970
Car Brand:Aston Martin | Country:UK | Car Model:DBS | Year:12-1965
Car Brand:Ford | Country:United States of America | Car Model:GT40 | Year:09-1966

出力:

1:Mercedes:Germany:300 SL:61:xxx
2:Lamborghini:Italy:Miura:51:xxx
3:Aston Martin:UK:DBS:56:xxx
4:Ford:United States of America:GT40:55:xxx

1,2,3,4 は行番号です。 61、52、56、55(現在の年、月無視)、xxx保険会社(常に同じであり、この部分は動作を停止しました)

スクリプト:

line=$(awk '{print NR}' file.txt)
brand=$(sed 's/.*Brand:\(.*\) | Country.*/\1/' file.txt)
country=$(sed 's/.*Country:\(.*\) | Year.*/\1/' file.txt)
sed 's/.*Year:\(.*\) | Car.*/\1/; s/^...//' file.txt > cars.txt
age=$(awk -v age="$(date +%Y)" '{print age - $1}' cars.txt)
model=$(sed 's/.*Model:\(.*\)*/\1/' file.txt)
echo "$(paste <(echo "$line") <(echo "$brand") <(echo "$country") <(echo "$age") <(echo "$model") -d ':')" > cars.txt
# sed -i 's/$/:xxx/' cars.txt
cat cars.txt

ありがとう

答え1

awkを使用してください。

$ awk -v yr="$(date +'%Y') " -F' *[:|-] *' -v OFS=':' '{print NR, $2, $4, $6, yr-$9, "xxx"}' file
1:Mercedes:Germany:300 SL:61:xxx
2:Lamborghini:Italy:Miura:51:xxx
3:Aston Martin:UK:DBS:56:xxx
4:Ford:United States of America:GT40:55:xxx

上記は、 、 と:|-に示された位置にしか現れないと仮定します。-ブランド名(例Mercedes-Benz:)または入力の他の場所に表示される場合は、上記の内容を次のように調整してください。

awk -v yr=$(date +%Y) -F' *[:|] *' -v OFS=':' '{sub(/.*-/,"",$8); print NR, $2, $4, $6, yr-$8, "xxx"}' file

たとえば、

$ cat file
Car Brand:Mercedes-Benz | Country:Germany | Car Model:300 SL | Year:04-1960
Car Brand:Lamborghini | Country:Italy | Car Model:Miura | Year:10-1970
Car Brand:Aston Martin | Country:UK | Car Model:DBS | Year:12-1965
Car Brand:Ford | Country:United States of America | Car Model:GT40 | Year:09-1966

$ awk -v yr=$(date +%Y) -F' *[:|] *' -v OFS=':' '{sub(/.*-/,"",$8); print NR, $2, $4, $6, yr-$8, "xxx"}' file
1:Mercedes-Benz:Germany:300 SL:61:xxx
2:Lamborghini:Italy:Miura:51:xxx
3:Aston Martin:UK:DBS:56:xxx
4:Ford:United States of America:GT40:55:xxx

表示されている場所とは異なる場所に表示される可能性がある場合は、実際のデータをより現実的に表現できるように例を変更して:ください。|

答え2

GNU awkと適切なフィールド区切り記号(FS)と出力フィールド区切り記号(OFS)を使用してください。

gawk -F '|' -v OFS=: -v yr="$(date +%Y)" '
{ 
  for (i=1; i<=NF; i++) {
    gsub(/^\s+|\s+$/, "", $i)
    sub(/.*:/, "", $i)
    if (i==NF) {
      sub(/[^-]+/, "", $i)
      $i += yr
    }
  }
  print NR, $0, "xxx"
}
' file

出力:

1:Mercedes:Germany:300 SL:61:xxx
2:Lamborghini:Italy:Miura:51:xxx
3:Aston Martin:UK:DBS:56:xxx
4:Ford:United States of America:GT40:55:xxx

答え3

使用できるミラー(既定値)区切り値のキーと値のペア(「dkvp」)形式を「csvlite」(または「csv」)に変換します。

$ cat file
Car Brand:Mercedes | Country:Germany | Car Model:300 SL | Year:04-1960
Car Brand:Lamborghini | Country:Italy | Car Model:Miura | Year:10-1970
Car Brand:Aston Martin | Country:UK | Car Model:DBS | Year:12-1965
Car Brand:Ford | Country:United States of America | Car Model:GT40 | Year:09-1966

それから

$ mlr --ifs ' | ' --ips ':' --ocsvlite --ofs ':' \
    put '$Item = NR; $Year = strftime(strptime($Year,"%m-%Y"),"%y"); ${Insurance Co} = "xxx"' \
    then reorder -f Item file
Item:Car Brand:Country:Car Model:Year:Insurance Co
1:Mercedes:Germany:300 SL:60:xxx
2:Lamborghini:Italy:Miura:70:xxx
3:Aston Martin:UK:DBS:65:xxx
4:Ford:United States of America:GT40:66:xxx

--headerless-csv-outputCSVヘッダーが必要ない場合は追加してください。

答え4

awk -F "[:|]" '{print NR":"$2":"$4":"$6":",strftime("%Y-%m-%d")-substr($NF,4)":xxx"}'  filename

出力

1:Mercedes:Germany:300 SL:61:xxx
2:Lamborghini:Italy:Miura:51:xxx
3:Aston Martin:UK:DBS:56:xxx
4:Ford:United States of America:GT40:55:xxx

関連情報