你能帮我简化这个脚本吗?
这可行,但我认为有一种更简单的方法可以做到这一点,但我找不到它。
文件:
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