J’ai un fichier texte comme celui-ci:
********** time1 ********** line of text1 line of text1.1 line of text1.2 ********** time2 ********** ********** time3 ********** ********** time4 ********** line of text2.1 line of text2.2 ********** time5 ********** ********** time6 ********** line of text3.1
Je veux extraire la ligne de texte et l’heure (sans les écanvass) au-dessus et la stocker dans un fichier (le temps sans ligne de texte en dessous doit être ignoré ). Je veux le faire de préférence avec grep et awk. Donc, par exemple, ma sortie pour le code ci-dessus devrait être
time1 : line of text1 time1 : line of text1.1 time1 : line of text1.2 time4 : line of text2.1 time4 : line of text2.2 time6 : line of text3
comment puis-je y aller?
Cela suppose qu’il n’y a pas d’espace dans le temps et qu’il n’y a qu’une seule ligne de texte après chaque marqueur de temps.
awk '$1 ~ /\*+/ {prev = $2} $1 !~ /\*+/ {print prev, ":", $0}' inputfile
Fonctionne avec des espaces dans le temps:
awk '/^[^*]+/ { gsub(/*/,"",x);printf x": "; print };{x=$0}' data.txt
Vous pouvez le faire comme ça avec vim
:
:%s_\*\+ \(YOUR TIME PATTERN\) \*\+\_.\(\[^*\].*\)$_\1 : \2_ | g_\*\+ YOUR TIME PATTERN \*\+_d
C’est-à-dire rechercher les lignes TIME PATTERN
et enregistrer le modèle de temps et la ligne suivante s’il n’a pas démarré avec *
. Ensuite, créez la nouvelle ligne à partir d’eux. Supprimez ensuite chaque ligne TIME PATTERN
restante.
Notez que cela suppose que les lignes de modèle de temps se terminent par *
, etc.
Avec awk
:
awk '/\*+ YOUR TIME PATTERN \*+/ { time=gensub("\*+ (YOUR TIME PATTERN) \*+","\\1","g") } ! /\*+ YOUR TIME PATTERN \*+/ { print time " : " $0 }' INPUTFILE
Et il y a d’autres façons de le faire.
En awk, voir:
#!/bin/bash awk ' BEGIN{ t=0 } { if ($0 ~ " time[0-9]+ ") { v=$2 t=1 } else if ($0 ~ "line of text") { if (t==1) { printf("%s : %s\n", v, $0) } else { t=0; } } } ' FILE
Remplacez simplement FILE
par votre nom de fichier.
Cela pourrait fonctionner pour vous (GNU sed):
sed '/^\*\+ \S\+.*/!d;s/[ *]//g;$!N;/\n[^*]/!D;s/\n/ : /' file
Explication:
*
si elles ne sont pas supprimées. /^\*\+ \S\+.*/!d
*
et les espaces (heure de départ). s/[ *]//g
$!N
*
sinon supprimez la première ligne /\n[^*]/!D
\n
par un espacement :
et imprimez. s/\n/ : /
awk '{ if( $0 ~ /^\*+ time[0-9] \*+$/ ) { time = $2 } else { print time " : " $0 } }' file
$ uniq -f 2 input-file | awk '{getline n; print $2 " : " n}'
Si votre horodatage contient des espaces, remplacez l’argument par l’option -f
afin uniq
compare uniquement la chaîne finale de *
. Par exemple, utilisez -f X
où X-2 est le nombre d’espaces dans l’horodatage. De même, s’il y a des espaces dans l’horodatage, le awk devra changer. L’un ou l’autre fonctionnera:
$ uniq -f 3 input-file | awk -F '**********' '{getline n; print $2 " : " n}' $ uniq -f 3 input-file | awk '{getline n; $1=""; $NF=""; print $0 ": " n }'