Jak optimalizovat skript pomocí NF a smyčky for

Mám několik souborů, každý s jiným počtem sloupců. Chci je převést a vložit je do databáze.

Například soubor test01:

0001 000000000000001 john smith 45 500 0002 000000000000002 peter jackson 20 80 0003 000000000000002 robert brown 35 100 0004 000000000000007 sarah white 40 300 

Můj požadovaný výstup je:

("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300"); 

k dosažení tohoto cíle používám následující skript:

cat test01 |awk -F"\t" "{print "("\"""$1""\"","\"""$2""\"","\"""$3""\"","\"""$4""\"","\"""$5""\""),"}" |sed "$ s/.$/;/" 

A funguje to dobře, problém je, když najdu jiný soubor s jiným počtem sloupců, takže musím skript upravit ručně.

Vím, že mohu získat počet sloupců s proměnnou NF AWK, ale jak kombinovat tuto proměnnou se smyčkou for ve skriptu?

Když to zkusím

cat test01 | awk "{for (i = 1; i <= NF; i++){print $i""\"","\"""}}" 

dostanu tento výsledek:

0001"," 000000000000001"," john"," smith"," 45"," 500"," 0002"," 000000000000002"," peter"," jackson"," 20"," 80"," 0003"," 000000000000002"," robert"," brown"," 35"," 100"," 0004"," 000000000000007"," sarah"," white"," 40"," 300"," 

Komentáře

  • Existuje v původním souboru oddělovač karet, nebo je to jen " nějaké mezery "?
  • Jedná se o oddělovač karet

Odpověď

Používání GNU sed:

$ sed -e "s/^/("/" -e "s/\t/","/g" -e "s/$/"),/" -e "$s/.$/;/" file ("0001","000000000000001","john smith","45","500"), ("0002","000000000000002","peter jackson","20","80"), ("0003","000000000000002","robert brown","35","100"), ("0004","000000000000007","sarah white","40","300"); 

skript má čtyři části:

  1. s/^/("/ nahradí začátek řádku (".
  2. s/\t/","/g nahradí karty za ",". Toto je bit, který vyžaduje GNU sed. U ostatních sed implementací vložte místo \t doslovnou tabulátor.
  3. s/$/"),/ nahradí konec řádku znakem "),.
  4. $s/.$/;/ nahradí čárku na konci poslední řádek (pouze) s ;.

Komentáře

  • Spustím skript a vybízí " > " tak, jak něco očekává
  • @ user3333911 Měl jsem neodpovídající citace, ze starší verze. Opraveno a otestováno.

Odpovědět

Pokud je váš vstupní soubor oddělen od karet, můžete zkusit následující:

awk -F"\t" -vq=""" -vOFS="","" "$1=$1 {print "(" q $0 q ");"}" filename 

Nebo vložte uvozovky do funkce tisku:

awk -F"\t" -vOFS="","" "$1=$1 {print "(" "\x27" $0 "\x27" ");"}" filename 

Komentáře

  • Sledujte čárky na konci všech řádků kromě posledního …
  • Všimněte si, že @Kusalananda. Udělal jsem rychlou opravu jako v awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'. Nějaký lepší návrh?
  • Ne, tato ' je dobrá oprava.

Odpověď

K dosažení stejného chování, jaké chcete u počátečního skriptu, můžete použít metodu awk „printf“. Umožňuje zbavit se nových řádků, které jsou vloženy pomocí „tisku“. Myslím, že váš skript by měl být přepsán takto:

cat test01 | awk "{for (i = 1; i <= NF; i++){printf $i""\"","\"""}; printf "\n";}" 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *