2013-10-12 6 views
0

Je cherche un moyen de supprimer des caractères spécifiques dans une chaîne correspondant à un motif regex. J'ai stocké du texte avec des sauts de ligne dans un fichier séparé par des tabulations supposé avoir un enregistrement par ligne et j'essaie de remplacer tous les sauts de ligne par des espaces. Les sauts de ligne ne se produisent pas dans la dernière colonne (qui est une colonne courte avec une clé alphanumérique).Remplacer un caractère spécifique dans un motif

La façon de le résoudre est à mon humble avis de remplacer toutes les occurrences de \n dans le schéma suivant:

[^\t]*\t[^\t]* 

Ma solution jusqu'à maintenant utilise trois étapes:

  1. remplacer le « bon » \n avec une chaîne spéciale absente du reste du texte (par exemple long nombre) en utilisant s/\([^\t]*\t{x}[^\t]*\)\n/\1#12398754987235649876234#/g avec x étant un de moins que le nombre prévu de colonnes dans mes fichiers
  2. remplacer tous les (« mauvais ») \n avec un espace
  3. remplacer le numéro long avec une nouvelle ligne

Mais j'ai tout à fait quelques giga-octets de fichiers texte et je suis à la recherche d'une façon de faire ceci dans un uniquesedétape.

Exemple d'entrée:

foo \t Each multiplex has screens allocated \n 
to each studio. \t abc \n 
bar \t The screens need filling. \t bcd \n 
123 \t Studios have to create product to fill \n 
their screen, and the amount of good product is limited. \t cde \n 

Sortie:

foo \t Each multiplex has screens allocated to each studio. \t abc \n 
bar \t The screens need filling. \t bcd \n 
123 \t Studios have to create product to fill their screen, and the amount of good product is limited. \t cde \n 
+0

Les lignes commencent-elles littéralement par un nombre? – Bohemian

+0

Non. J'ai modifié mon exemple pour supprimer l'ambiguïté.Il n'y a AUCUN pattern dans les colonnes (peut être du texte, des chiffres, de la ponctuation ...), sauf pour le '\ t 'qui est seulement utilisé pour séparer les colonnes. – ATN

+0

Vous essayez d'enlever tout '\ n' qui ne * suit * pas". ", N'est-ce pas? – Beta

Répondre

0

Il est toujours difficile de gérer les lignes précédentes avec , en raison de ses limites de petit nombre de tampons, quantificateurs avides, le manque de anticipation, et beaucoup plus, mais ici vous avez une approche. Il a commenté, mais je sais que ce n'est pas facile à suivre

sed -n ' 
    ## Label "a" 
    :a; 
    ## Enter this section after join all lines without a tab. 
    /\t.*\t/ { 
     ## Loop to remove all newlines but the last one, because it is 
     ## next line with a tab that I dont want to print now. 
     :b; 
     /\n[^\n]*\n/ { 
      s/\n/ /; 
      bb 
     }; 
     ## Print until newline (all joined lines) and delete them 
     P; 
     D; 
    }; 
    ## Append next line to buffer and repeat loop. 
    N; 
    $! ba; 
    ## Special case for last line, remove extra newlines and print. 
    s/\n/ /g; 
    p 
' infile 

En supposant infile avec le contenu suivant:

foo  Each multiplex has screens allocated 
to each studio. 
bar  The screens need filling. 
123  Studios have to create product to fill 
their screen, and the amount of good product is limited. 

Il donne:

foo  Each multiplex has screens allocated to each studio. 
bar  The screens need filling. 
123  Studios have to create product to fill their screen, and the amount of good product is limited. 
1

En utilisant awk

cat file 
foo  Each multiplex has screens allocated 
to each studio. 
bar  The screens need filling. 
123  Studios have to create product to fill 
their screen, and the amount of good product is limited. 

Si une ligne contient l'onglet \t, connectez-le à la ligne suivante.

awk 'NR>1 {s=/\t/?"\n":" "}{printf s"%s",$0} END {print ""}' 
foo  Each multiplex has screens allocated to each studio. 
bar  The screens need filling. 
123  Studios have to create product to fill their screen, and the amount of good product is limited. 
1

Cela pourrait fonctionner pour vous (GNU sed):

sed -r ':a;$!N;s/\n([^\t]+)$/\1/;ta;P;D' file 

Lire 2 lignes dans l'espace de travail (PS) et si la dernière ligne ne contient pas d'onglet, retirez la nouvelle ligne et lisez dans la ligne suivante et répétez. Si la ligne contient un onglet, imprimez la première ligne, puis supprimez-la et répétez.

Questions connexes