Comment utiliser ^ # $ comme séparateur d'enregistrement dans awk?

8

Comment dites-vous à awk d'utiliser un #caractère seul dans une ligne comme séparateur d'enregistrement? Le problème est que vous ne pouvez pas le dire RS="^#$"car ^correspond au début du fichier, pas au début d'une ligne, et RS="#\n"ne fonctionne pas non plus car il correspond à des #caractères qui ne sont pas au début d'une ligne.

$ data='#
first record, first field
first record, second field
#
second record, first field#
second record, second field
'

Imprimez ensuite le premier champ de chaque enregistrement en utilisant RS="#\n":

$ printf "%s" "$data" | awk '
  BEGIN { RS="#\n"; FS="\n" }
  /./ {print $1}
  '
first record, first field
second record, first field
second record, second field

La dernière ligne est fausse car ce n'est pas le premier champ mais le second. La sortie prévue était

first record, first field
second record, first field#
Ernest A
la source
1
Pourriez-vous s'il vous plaît également fournir un exemple de la sortie dont vous avez besoin
roaima
pour que vos données ressemblent line one#line two#line three?
Skaperen
et RS="#"fait quoi?
Skaperen
@Skaperen non, les données ressemblent #\nrecord one\n#\nrecord twoet chaque enregistrement se compose de plusieurs \nchamps séparés.
Ernest A
RS='#\n'devrait fonctionner afaik - bien qu'il traite l'initiale #comme mettant fin à un enregistrement vide (c'est-à-dire que toutes les NRvaleurs seront "désactivées" par un)
steeldriver

Réponses:

6

Voici une façon de le faire dans awk:

$ printf "%s\n" "$data" | 
    awk -F'\n' -v RS='(^|\n)#\n' '/./ {print $1}' 
first record, first field
second record, first field#

L'astuce consiste à définir le séparateur d'enregistrement pour soit le début du fichier ( ^), ou un saut de ligne, suivi d'un #et un autre saut de ligne \n.


terdon
la source
1
Notez que les NR seront uniques dans ce cas (essayez de les remplacer /./par NR==1). Je pense que la solution la plus simple serait de terminer le fichier / données - au lieu de commencer - par une #ligne distincte. Ensuite, \n#\npourrait être utilisé comme RS et cela fonctionnerait correctement.
don_crissti
@don_crissti Je viens de copier cela depuis l'OP. Je suppose qu'ils l'utilisent pour éviter les lignes vides, donc NR==1cela ne fonctionnera pas s'il y a plus de lignes vides plus bas.
terdon