Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I Have a file that has text like this:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

etc...

And i want to match up the Alphabetic lines with the Numeric lines so they are like this:

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

Does anyone know of a simple way to achieve this?

share|improve this question
    
You mention emacs.. Are you looking for an elisp solution, or how to run a shell-script from within emacs? –  Peter.O Mar 24 '12 at 15:10
add comment

6 Answers

up vote 3 down vote accepted

One way using perl:

Content of script.pl:

use warnings;
use strict;

## Check arguments.
die qq[Usage: perl $0 <input-file>\n] unless @ARGV == 1;

my (@alpha, @digit);

while ( <> ) {
        ## Omit blank lines.
        next if m/\A\s*\Z/;

        ## Remove leading and trailing spaces.
        s/\A\s*//;
        s/\s*\Z//;

        ## Save alphanumeric fields and fields with
        ## only digits to different arrays.
        if ( m/\A[[:alpha:]]+\Z/ ) {
                push @alpha, $_;
        }
        elsif ( m/\A[[:digit:]]+\Z/ ) {
                push @digit, $_;
        }
}

## Get same positions from both arrays and print them
## in the same line.
for my $i ( 0 .. $#alpha ) {
        printf qq[%s %s\n], $alpha[ $i ], $digit[ $i ];
}

Content of infile:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

Run it like:

perl script.pl infile

And result:

AAAA 1234
BBBB 5678
CCCC 9012
DDDD 3456
EEEE 7890
share|improve this answer
    
Thanks! Worked like a charm :) –  NWS Mar 24 '12 at 16:22
    
Interesting... Your two regex substitution lines which Remove leading and trailing spaces run about 1.6 times faster than a single line which uses backreferencing and non-greedy: s/\A\s*(.*?)\s*\Z/\1/. –  Peter.O Mar 26 '12 at 15:08
add comment

In awk, preserving empty lines, assuming the file is well formatted, but logic could be added to check the file:

awk -v RS="" '{for(i=1; i<=NF; i++) a[i]=$i
  getline
  for(i=1; i<=NF; i++) print a[i] " " $i
  print ""}' file
share|improve this answer
add comment
<input sed -nr '/^[A-Z]{4}$/,/^$/w out1
                /^[0-9]{4}$/,/^$/w out2'
paste -d' ' out1 out2 |sed 's/^ $//' 

or, in a single step, without temp files

paste -d' ' <(sed -nr '/^[A-Z]{4}$/,/^$/p' input) \
            <(sed -nr '/^[0-9]{4}$/,/^$/p' input) | sed 's/^ $//' 

The last sed step removes the delimiter on the blank lines, which is introduced by paste...

share|improve this answer
add comment

With emacs use rectangle operations to cut the text lines and paste them before the numerical lines.

share|improve this answer
    
Thanks, but not really suitable for 15000+ lines! + 1 for a working idea and you need the rep :) –  NWS Mar 24 '12 at 16:21
add comment

If the entries are in order,

  1. Split the input into alphabetic entries and numeric entries, using grep:

    • grep "[[:alpha:]]\+" < file > alpha
    • grep "[[:digit:]]\+" < file > digit
  2. Join the two resulting files, alpha and digit, using paste:

    • paste alpha digit (you can add -d " " so it uses a space instead of a tab)
share|improve this answer
1  
Without temp files: paste <(grep "[[:alpha:]]\+" file) <(grep "[[:digit:]]\+" file) or with a single process substitution: grep "[[:alpha:]]\+" file | paste - <(grep "[[:digit:]]\+" file). –  jfgagne Mar 24 '12 at 18:52
add comment

Too bad awk doesn't have nice push/pop/unshift/shift functions. Here's a short Perl snippet

perl -M5.010 -lne '
  given ($_) {
    when (/^[[:alpha:]]+$/) {push @alpha, $_}
    when (/^\d+$/) {say shift(@alpha), " ", $_}
    default {say}
  }
'
share|improve this answer
    
When I run it, it outputs an extra (leading) blank line per group. –  Peter.O Mar 26 '12 at 8:41
    
Due to the default clause, blank lines are immediately printed, so the blank before "1234" will show before the "AAAA" line. –  glenn jackman Mar 26 '12 at 10:47
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.