2009-09-29 9 views
0

J'ai des données qui ressemble à ceci:ligne de jonction rompt avec condition dans ETD

> sq1 
foofoofoobar 
foofoofoo 
> sq2 
quxquxquxbar 
quxquxquxbar 
quxx 
> sq3 
foofoofoobar 
foofoofoo 
> sq4 
foofoofoobar 
foofoo 

Je veux rejoindre les lignes sur la base d'en-tête « > SQI » comme ligne de coupure, -à-dire qui donne:

foofoofoobarfoofoofoo 
quxquxquxbarquxquxquxbarquxx 
foofoofoobarfoofoofoo 
foofoofoobarfoofoo 

J'ai essayé d'utiliser cette sed mais échouent:

sed '/^S/d;N;s/\n/\t/' 

Quelle est la bonne façon de le faire?

Répondre

3
#!/bin/sed -f 

# If this is a header line, empty it... 
s/^>.*// 
# ... and then jump to the 'end' label. 
t end 
# Otherwise, append this data line to the hold space. 
H 
# If this is not the last line, continue to the next line. 
$!d 
# Otherwise, this is the end of the file or the start of a header. 
: end 
# Call up the data lines we last saw (putting the empty line in the hold). 
x 
# If we haven't seen any data lines recently, continue to the next line. 
/^$/d 
# Otherwise, strip the newlines and print. 
s/\n//g 

# The one-line version: 
# sed -e 's/^>.*//;te' -e 'H;$!d;:e' -e 'x;/^$/d;s/\n//g' 
1

Vous testez un «S» majuscule au début de la ligne. Vous devriez tester le caractère plus grand que:

sed '/^>/d;N;s/\n/\t/' 

ou

sed '/^> sq/d;N;s/\n/\t/' 

Modifier: J'ai raté le fait qu'il y ait un nombre variable de lignes entre les en-têtes. C'est ce que je jusqu'à présent:

sed -n '/^>/{x; p; d}; /^>/!H; x; s/\n/\t/; h; $p' 

Malheureusement, cela laisse dans l'en-tête:

> sq1 foofoofoobar foofoofoo 
> sq2 quxquxquxbar quxquxquxbar quxx 
> sq3 foofoofoobar foofoofoo 
> sq4 foofoofoobar foofoo 

Si vous faites cela à partir d'une invite Bash, vous pouvez avoir à faire set +H d'abord si vous n » t obtenir l'interférence d'expansion de l'histoire à cause du point d'exclamation.

Edit2: Ma version révisée qui se débarrasse des têtes:

sed -n '1{x;d};/^>/{x; p; d}; H; x; s/\n/\t/; s/^>.*\t//; h; $p' 
+0

@DW: votre extrait ne semble pas fonctionner. J'ai reçu "foofoofoobartfoofoofoo" quxquxquxbartquxquxquxbar \ n quxxt> sq3 \ n foofoofoobartfoofoofoo \ n foofoofoobartfoofoo " – neversaint

1

Une solution bash pour la question initiale (sans "têtes".):

#!/bin/bash 
text=[] 
i=0 

exec <$1 

while read line 
do 
    text[$i]=$line 
    let "i += 1" 
done 


j=0 
len=0 
while [ $j -lt ${#text[@]} ] 
do 
    string=${text[$j]} 
    if [ $len -le ${#string} ] ; then 
     printf $string 
    else 
     printf $string'\n' 
    fi 
    len=${#string} 
    let "j += 1" 
done 
printf '\n' 
1

je peux pas trouver un moyen simple de le faire dans sed. Quoi qu'il en soit, avec gawk/mawk il vous suffit de changer la RS variable et couper des caractères de nouvelle ligne:

awk -v RS='> sq[0-9]' 'NR>1{gsub(/\n/,"");print}' file 
Questions connexes