我怎样才能简化这个?

我怎样才能简化这个?

你能帮我简化这个脚本吗?

这可行,但我认为有一种更简单的方法可以做到这一点,但我找不到它。

文件:

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

上面假设:|、 和-只能出现在示例中显示的位置。如果 a-可以出现在品牌名称(例如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-output如果您不需要 CSV 标头,请添加。

答案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

相关内容