2013-02-23 4 views
2

Je souhaite supprimer les lignes vides (nouvelles lignes, tabulations et espaces) dans le fichier avec sed ou awk, mais uniquement si ces lignes vides sont entre deux motifs.Supprimer les lignes vides entre les motifs

lorem lorem PATTERN1 

\t 

PATTERN2 lorem2 lorem2` 

Je m'attends au résultat ci-dessous qui est une concaténation de 2 lignes avec les deux modèles.

lorem lorem PATTERN1PATTERN2 lorem2 lorem2 
+0

sed Fichier "/ PATTERN1 /, PATTERN2/d" – user537723

Répondre

5

Cela pourrait fonctionner pour vous (GNU sed):

sed -r '/PATTERN1/!b;:a;/PATTERN2/bb;$!{N;ba};:b;s/(PATTERN1.*)[ \t\n]+(.*PATTERN2)/\1\2/;tb' file 
  • /PATTERN1/!b juste imprimer la ligne à moins qu'il contient le premier motif
  • :a;/PATTERN2/bb;$!{N;ba} lire les lignes suivantes dans l'espace de travail (PS) jusqu'à ce que le second motif soit rencontré
  • :b;s/(PATTERN1.*)[ \t\n]+(.*PATTERN2)/;tb Remplacer tous les espaces, tabulations et retours à la ligne entre le premier et le second les sternes.
+0

Pourriez-vous expliquer cette magie? – user537723

+0

@ user537723 voir modifier – potong

0

Si vous voulez juste supprimer des lignes qui ne contiennent que des espaces entre les lignes qui contiennent PATTERN1 et PATTERN2, il suffit de faire:

sed '/PATTERN1/,/PATTERN2/{ /^[ \t]*$/d}' 

Dans l'exemple de sortie que vous donnez, il semble que vous voulez aussi éliminer la nouvelle ligne qui suit PATTERN1, mais on ne sait pas comment vous voulez traiter comme entrée:

PATTERN1 
non-empty-line 

PATTERN2 

, ni la façon dont vous voulez gérer

PATTERN1 non-whitesapce 
PATTERN2 

Une clarification de la question est peut-être nécessaire. Si vous voulez vraiment juste pour éliminer tous les espaces entre pattern1 et pattern2, il est probablement plus facile avec:

perl -0777 -pe 's/(pattern1)\s*(pattern2)/$1$2/g' 
0

@ user537723: vous pouvez essayer awk:

--- amélioration post précédent, il imprime sur un ligne entre les motifs ---

awk '/PATTERN1/{ORS=x} /PATTERN2/{ORS=RS} ORS || NF' file 
+0

A changé mon post pour qu'il soit sur une ligne maintenant ... – Scrutinizer

1

GNU awk équivalent de script Perl de @ WilliamPursell:

awk -v RS='\0' '{print gensub(/(PATTERN1).*(PATTERN2)/,"\\1\\2","g")}' file 
Questions connexes