comment split file et lignes

J'ai un file text comme:

1_01 { ; quite good spirals reset=2000 type=mandel passes=1 corners=-0.6014129278/-0.5990935452/0.427747516/0.429487053 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 1_02 { ; ssortingngy one, with dist estimator reset=2000 type=mandel passes=1 corners=-1.9228429644992/-1.9228427944992/-6.3749991620026e-008/6.375000\ 8379971e-008 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/20/320/200 } 1_03 { ; OK, bit dull, not zoomed in far reset=2000 type=mandel passes=1 corners=0.3734922373/0.3820837907/-0.243292645/-0.23684898 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 1_04 { ; a mess, needs dist est reset=2000 type=mandel passes=1 corners=-1.862224008886682/-1.86222400040936/-3.214020831358832e-009/3.1\ 43970347410528e-009 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 

et je voudrais le split en files et lignes comme:

 1_01 { ; quite good spirals reset=2000 type=mandel passes=1 corners=-0.6014129278/-0.5990935452/0.427747516/0.429487053 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 

Maintenant, j'ai fait un script bash:

 #!/usr/bin/env bash # chmod +x s.sh # ./s.sh for f in *.txt; do echo " found "$f " file "; #split -l 7 $f; awk '/{/{n++}{print > n".p" }' $f echo $f "- split when { is found and add p extension " ; rm $f; echo " input file " $f " is removed " ; done for f in *.p; do echo " in "$f " file replace space with newline and add par extension" # tr '{}' '()' < infile > outfile tr ' ' '\n' < $f >$f"ar" rm $f; done for f in *.par; do echo "remove blank= empty lines" sed -i '/^$/d' $f done 

Ça marche, mais est-ce que je peux le faire mieux?

MISE À JOUR: simpifié et testé dans Gawk (v.3.1.8) et mawk (1.3.3)

Ce script awk devrait faire ce que vous semblez requestr; il peut fonctionner sur d'autres implémentations awk prenant en charge les séparateurs de champs et d'loggings d'expressions régulières:

 #!/usr/bin/awk -f BEGIN { RS="}\n\n?" ORS="}\n" FS="\n" OFS="\n" } { # compress whitespace in first field gsub(/[ \t\n]+/," ",$1) # split remaining fields on whitespace for (i=2;i<=NF;i++) { gsub(/[ \t\n]+/,"\n",$i) } # remove double-newlines resulting from trailing whitespace gsub("\n\n+","\n",$0) print > NR".par" } 

Test avec votre input en tant que file.txt :

 $ ./split.awk file.txt 

puis

 $ cat 1.par 1_01 { ; quite good spirals reset=2000 type=mandel passes=1 corners=-0.6014129278/-0.5990935452/0.427747516/0.429487053 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 

et

 $ cat 3.par 1_03 { ; OK, bit dull, not zoomed in far reset=2000 type=mandel passes=1 corners=0.3734922373/0.3820837907/-0.243292645/-0.23684898 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 

Je mets vos données d'exemple dans ./file comme:

 cat >file <<\IN # all of your example IN 

Ensuite, j'ai fait ce qui suit:

 sed -n 's|\([^ ]*\) *{.*|/\1 {/,/}/w file.\1.par|p' file | sed -e 's/ */ /g;s/^ //;s/ $//;/./!d;/{/!y/ /\n/' -f - file 

Cela utilise un process sed pour élaguer datatables dans le file infile et le modifier dans un script sed utilisable pour un second process sed .

Le script qui se termine en cours d'exécution ressemble à …

 /1_01 {/,/}/w file.1_01.par /1_02 {/,/}/w file.1_02.par /1_03 {/,/}/w file.1_03.par /1_04 {/,/}/w file.1_04.par 

… mais il n'est exécuté qu'après le second sed pour chaque ligne du file

 ... -e 's/ */ /g;s/^ //;s/ $//;/./!d;/{/!y/ /\n/' ... 

… qui d'abord compresse n'importe quelle séquence d'espaces en un seul espace, supprime un espace de début ou de fin s'ils le restnt, supprime les lignes vides entièrement de la sortie et convertit en dernier lieu tous les espaces en un caractère \n Ewline pour chaque ligne qui ne correspond pas { .

Ainsi, pour chaque numéro de ligne qui correspond (section heading) *{.* Le second file.(section heading) le transfère et toutes les lignes subséquentes jusqu'à la prochaine occurrence } en input dans le file.(section heading) .

Après avoir couru que j'ai fait …

 cat <./file.1_01.par 

…et…

 1_01 { ; quite good spirals reset=2000 type=mandel passes=1 corners=-0.6014129278/-0.5990935452/0.427747516/0.429487053 params=0/0 float=y maxiter=1000 inside=0 outside=15 distest=1/10/320/200 } 

Pour l'exécuter il suffit de copyr / coller ces deux lignes sed ... dans votre terminal et substituer le nom du file pour tout ce qui est approprié.

J'ai aussi eu un coup au lien dans votre question …

 sed -n 's|.\([^ ]*\) {.*|/\1 {/,/^}$/w \1.par|p' <<-IN |\ sed -e 's/.//;/{/!y/ /\n/' -f - all.par $(curl -s 'http://www.calresco.org/pic3/calres3.par' | tr -s '\r\n ' '\n ' |tee all.par) IN 

Cela sépare toutes les fonctions .par dans leurs propres files – et gère les fins de ligne DOS:

 ls -C a46.par bugeyed.par flocks.par iconw2b.par manchaos.par swirl5.par aciddrop.par burr.par galaxy.par juliland.par mandelzm.par sortingfic.par all.par complex.par highrise.par lace.par redgiant.par angfish.par eyeeye.par iconvolc.par lavaflow.par scythe.par 

Ils sont tous nommés pour le nom de la fonction.

 cat galaxy.par galaxy {;Chris Lucas reset=1950 type=julia center-mag=+0.03023290053994965/+0.26628255550711930/42.69126/1/67.5 params=-0.1582146627566066/0.6550294654497986 float=y maxiter=30000 colors=000000GFF<28>x11z00z10<29>zx0zz0zz1<29>zzxzzzzzz<61>zV1zU0zU0zT0<\ 28>z10z00z00y00<30>c00b11a11`22_22<25>FFF } 

Essayez csplit: inputfile == frac.txt , files de sortie == frac[nn] (où nn> 00, car le file # 00 est vide)

  csplit -f frac frac.txt /^1/ {*} 

Line formatting, vous pouvez le faire par sed seul:

 sed -i 's/^\s*\|\s*$//g ; s/\s\s*/ /g ; /[{}]/!s/ /\n/g ; /^\s*$/d' *.txt