A szkript optimalizálása az NF és a for ciklus használatával

Több fájlom van, mindegyiknek különböző oszlopszáma van. Konvertálni szeretném őket, hogy beillesszék őket egy adatbázisba

Például a test01 fájl:

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

A kívánt kimenetem:

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

ennek eléréséhez a következő szkriptet használom:

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

És jól is működik, a probléma az, amikor találok egy másik fájlt, eltérő oszlopszámmal, ezért manuálisan kell módosítanom a szkriptet.

Tudom, hogy az AWK NF változójával el tudom kapni az oszlopok számát, de hogyan kombinálni ezt a változót a for ciklussal a szkriptben?

Amikor megpróbálom

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

Ezt az eredményt kapom:

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

Megjegyzések

  • Az eredeti fájlban van-e tabulátor elválasztó, vagy csak " néhány szóköz "?
  • Ez egy tabulátor elválasztó

Válasz

A GNU használata 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"); 

A szkript négy részből áll:

  1. s/^/("/ a sor elejét (".
  2. s/\t/","/g a füleket "," helyettesíti. Ez az a bit, amelyhez GNU szükséges sed. Más sed megvalósításokhoz szúrjon be egy szófület az \t helyére.
  3. s/$/"),/ a sor végét "), váltja fel.
  4. $s/.$/;/ a vesszőt a sor végén utolsó sor (csak) a következővel: ;.

Megjegyzések

  • Futtatom a szkriptet és a " > " üzenetet várja valamire
  • @ user3333911 Nem megfelelő idézetek voltak, egy korábbi verzióból. Javítva és tesztelve.

Válasz

Ha a bemeneti fájl tabulátorral van elválasztva, megpróbálhatja a következőket:

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

Vagy idézőjeleket ágyazhat a nyomtatási funkcióba:

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

megjegyzések

  • Figyelje az összes sor végén található vesszőket, az utolsó kivételével …
  • Jó figyelmeztetés @Kusalananda. Gyorsan kijavítottam a awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/' dokumentumban leírtak szerint. Van valami jobb javaslat?
  • Nem, ez ' jó megoldás.

Válasz

Az eredeti szkript használatával megegyező viselkedés eléréséhez használhatja az awk “printf” módszerét. Lehetővé teszi az új sorok megszabadulását, amelyeket a “nyomtatás” tesz. Gondolom, a szkriptet így kell átírni:

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

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük