Fórum Root.cz
Hlavní témata => Vývoj => Téma založeno: M 14. 08. 2017, 14:13:03
-
Ahoj,
Rád bych vás tu požádal o pomoc.
Potřebuji rozparsovat csv soubor pomocí awk.
Jednotlivé sloupce jsou odděleny ;
String v jednotlivých sloupcích obsahuje mezery.
awk -F";" '{print $1":"$2":"$3}'
mi bohužel s mezerami nefunguje.
Příklad mého CSV.
sloupec1 s mezerami;sloupec2;Sloupec3 s mezerami
Předem díky za radu :)
-
Zvláštní...
# awk -F";" '{print $1":"$2":"$3}' test.csv
sloupec1 s mezerami:sloupec2:Sloupec3 s mezerami
mně to normálně funguje...
# awk --version
GNU Awk 4.1.0, API: 1.0
-
pokud máš awk 3, mělo by ti fungovat
awk 'BEGIN { FS=";" } {print $1":"$2":"$3}'
-
Okrem FS(=Field Separator) je mozne definovat aj OFS (=output FS). Potom sa to da takto:
awk 'BEGIN{FS=";";OFS=":"} {print $1,$2,$3}' my_file.csv
alebo
awk -F';' 'BEGIN{FS=";";OFS=":"} {print $1,$2,$3}' my_file.csv
-
Díky všem za odpovědi!
Máte pravdu. AWK (GNU Awk 3.1.8) funguje a rozhází se mi to až v následné iteraci, což jsem nepředpokládal.
OPTIONS=`cat $SOURCE_LIST | awk -F";" 'NR>1 {print $1":"$2":"$3}'`
X=0
for LINES in $OPTIONS
do
X=$((X+1))
CHOICE[$X]=`echo $LINES`
echo $X "=" ${CHOICE[${X}]}
done
Zdrojové testovací řádky vypadají takto:
Schema full exp;/vymyslena/cesta.sh;Fu ll
D Bfu lle xp;/vymyslena/cesta2.sh;DD BB
A dostávám:
1 = Schema
2 = full
3 = exp:/vymyslena/cesta.sh:Fu
4 = ll
5 = D
6 = Bfu
7 = lle
8 = xp:/vymyslena/cesta2.sh:DD
9 = BB
-
for in v bashi má jako výchozí oddělovač i mezery, musíš ho nastavit pouze na zalomení řádku. Tj.
OPTIONS=`cat $SOURCE_LIST | awk -F";" 'NR>1 {print $1":"$2":"$3}'`
X=0
IFS=$'\n'
for LINES in $OPTIONS
do
X=$((X+1))
CHOICE[$X]=`echo $LINES`
echo $X "=" ${CHOICE[${X}]}
done
X=0
Pokud ale chceš vybrat ze souboru konkrétní řádek, je na to lepší třeba sed a rovnou můžeš jen ten jeden řádek prohnat awk. S tím NF nevím co děláš
sed -n $((X+1)),$((X+1))p $SOURCE_LIST | awk -F";" '{print $1":"$2":"$3}'
Případně to celé můžeš rovnou napsat v awk
X=0
cat $SOURCE_LIST | awk -v X="$X" -F";" 'NR == X+1 {print X+1" = "$1":"$2":"$3}'
Je ale otázka co řešíš, nejspíš to lze udělat daleko čištěji a stabilněji, stačí když sem popíšeš celý problém a nebudeš to kouskovat :)
-
rozparsovat jednotlive polia z CSV mozes rovno v awk, nemusis nato pouzivat dodatocne bash.
BEGIN {
FS=";"
# init array
delete words
n = 0
}
{
# add field to array
for(i=1; i<=NF; i++) {
words[++n] = $i
}
}
END {
# print results
for (i=1; i<=n; i++) {
printf("%d --> %s\n", i, words[i])
}
}
po sputeni je vysledok
$ awk -f m.awk m.csv
1 --> Schema full exp
2 --> /vymyslena/cesta.sh
3 --> Fu ll
4 --> D Bfu lle xp
5 --> /vymyslena/cesta2.sh
6 --> DD BB
-
@Tomas2 - Díky! Problém vyřešen nastavením oddělovače na zalomení řádku.
IFS=$'\n'
Celá myšlenka je následující.
Jde o interní řešení, kde máme několik bashových scriptů na jednotlivé úkony a vytvářím jakési centrální rozhraní, které načte všechny řádky s cestou, description a pod z csv a následně poskytne výběr, který úkon/script vykonat (proto potřebuji ten cyklus).
Pro základní činnosti tak vznikne lepší zastupitelnost.