我怎样才能简化这个脚本?

时间:2021-03-07 06:15:08

标签: linux bash awk sed

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

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

文件:

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

谢谢

3 个答案:

答案 0 :(得分:0)

这个怎么样:

sed 's/ *|[^:]*: */:/g' file.txt |
    awk -F: -v OFS=: -v year="$(date +%Y)" '{$1=NR; sub("^.*-","",$NF); $NF=year-$NF; print $0, "xxx"}'

说明:sed 命令用“:”替换了所有的“| Fieldlabel:”位,给出了这样的行:

Car Brand:Mercedes:Germany:300 SL:04-1960

awk 命令然后将其拆分为以冒号分隔的字段,用行号替换第一个字段,从最后一个(日期)中删除月份并从当前年份中减去它,最后它是打印在末尾添加了一个额外的固定字段。

答案 1 :(得分:0)

假设除了最后一项之外没有破折号 -,你可以这样做:

awk -v year="$(date +%Y)" -F '(-|:| \\| )' '{print NR":"$2":"$4":"$6":"(year-$9)":xxx"}' file.txt

-F 采用三个字段分隔符,- :|

管道 |(单个字符)是 3 个正则表达式的分隔符。 |(一个空格后接|,后接另一个空格)是分隔符之一,为了将数据文件中的管道与作为正则表达式分隔符的管道区分开来,我们需要用\\对其进行转义。

-F fs
  --field-separator fs
  Use fs for the input field separator (the value of the FS predefined variable).

欲知更多信息:https://www.gnu.org/software/gawk/manual/gawk.html#Regexp-Field-Splitting

答案 2 :(得分:0)

这可能对你有用(GNU sed):

sed -E 's/^/ | /;s/ | [^:]*//g;s/(.*:)..(.*)/\1$(($(date +%Y)\2)):xxx/;=' file |
sed 'N;s/\n//;s/.*/echo "&"/e'

预先准备一个管道分隔符,以便稍后预先添加行号。

全局删除管道分隔符和下一个 : 字符之间的文本。

用 bash 表达式替换最后一个字段(日期),该表达式计算与当前年份的年差,并附加一个虚拟字段 xxx

将当前行号添加到输出中。

将结果的内容传递给第二个 sed 调用,该调用将行号与该行的内容结合起来,并通过前置的 echo 命令评估 bash 表达式。