POS/Predrok 2021

Izvor: SI Wiki
< ПОС
Datum izmene: 18. jun 2021. u 14:17; autor: Fedja (razgovor | doprinosi) (navodnici)
Pređi na navigaciju Pređi na pretragu

Predrok traje 120 minuta.

Zadatak 2

Postavka

(15p) Napisati bash skriptu koja pronalazi sve celobrojne i realne konstante definisane kao makroe unutar .c datoteka. Konstana[sic] se definiše kao makro u formatu:

#define nazivKonstante vrednost

Skripta prima sledeće argumente:

  • jedini pozicioni argument je putanja do direktorijuma koji treba pretražiti do prizvoljne dubine. Ovaj direktorijum i svi njegovi poddirektorijumi sadrže .c datoteke unutar kojih treba pronaći konstante definisane kao makroe;
  • opcija -o sa argumentom koji predstavlja putanju do datoteke u koju je potrebno upisati u zasebnom redu nazivKonstante=vrednost za svaku konstantu koja se pronađe;
  • opcija -s bez argumenta treba da ispiše zbir svih celobrojnih konstanti nakon završetka skripte u formatu "Zbir je: zbir";
  • opcija -z sa argumentom koji predstavlja direktorijum u kome treba napraviti datoteku pod nazivom arhiva koja sadrži komprimovane i arhivirane samo one .c datoteke u kojima je pronađena bar jedna konstanta koja je definisana kao makro.

Opcija o je obavezna, dok opsije s i z nisu obavezne. Ispisivati kratke poruke o greškama u slučaju nekorektnih argumenata prilikom pokretanja skripte i takvim slučajevima prekinuti rad skripte.

Rešenje

#!/bin/bash

dst_path=
zbir=
arh_dir=

while getopts ":o:sz:" opt; do
    case $opt in
        o) dst_path=$OPTARG
            ;;
        s) zbir=1
            ;;
        z) arh_dir=$OPTARG
            ;;
        *) printf -- 'korišćenje: ./skripta.sh -o putanja [-s] [-z arhiva] [-h]\n'
            exit 1
            ;;
    esac
done

shift $(($OPTIND - 1))
src_path="$1"

if [ -z "$src_path" ]; then
    printf -- 'pozicioni argument skripte je obavezan\n'
    exit 2
fi
if [ -z "$dst_path" ]; then
    printf -- 'argument skripte -o je obavezan\n'
    exit 3
fi

temp=$(mktemp)

grep -rE '^#define \w+ [0-9]+(\.[0-9]*)?$' $src_path > $temp # uzmi sve celobrojne ili realne brojeve

sed -E 's/^.*#define (\w+) ([0-9]+(\.[0-9]*)?)$/\1=\2/' $temp > $dst_path

[ $zbir ] && sed -E 's/^.*=(.*)$/\1/' $dst_path | awk '{s += $1} END {print "Zbir je: " s}'

[ ! $arh_dir ] && tar -cvfz arhiva -T <(sed 's|:.*$||' $temp | uniq) # ovo ne radi ako neki od fajlova ima ':' u svom imenu zbog greedy .*, ali to je valjda dovoljno razumna pretpostavka