이것을 어떻게 단순화할 수 있습니까?

이것을 어떻게 단순화할 수 있습니까?

이 스크립트를 단순화하는 데 도움을 주실 수 있나요?

이것은 작동하지만 더 쉬운 방법이 있다고 생각하지만 찾을 수 없습니다.

문서:

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

관련 정보