シェルでアルファベット行のテキストと数字行のテキストを結合するにはどうすればよいでしょうか?

シェルでアルファベット行のテキストと数字行のテキストを結合するにはどうすればよいでしょうか?

次のようなテキストを含むファイルがあります:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

等...

そして、アルファベットの行と数字の行を次のように一致させたいと思います。

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

これを実現する簡単な方法を知っている人はいますか?

答え1

ではawk、ファイルが適切にフォーマットされていると想定して空行を保持しますが、ファイルをチェックするためのロジックを追加することもできます。

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

答え2

<input sed -nr '/^[A-Z]{4}$/,/^$/w out1
                /^[0-9]{4}$/,/^$/w out2'
paste -d' ' out1 out2 |sed 's/^ $//' 

または、一時ファイルなしで1ステップで

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

最後のステップでは、 ...sedによって導入された空白行の区切り文字を削除します。paste

答え3

使用方法の1つperl:

の内容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 ];
}

の内容infile

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

次のように実行します:

perl script.pl infile

そして結果:

AAAA 1234
BBBB 5678
CCCC 9012
DDDD 3456
EEEE 7890

答え4

エントリーが順番通りであれば、

  1. 次を使用して、入力をアルファベットのエントリと数字のエントリに分割しますgrep

    • grep "[[:alpha:]]\+" < file > alpha
    • grep "[[:digit:]]\+" < file > digit
  2. alphadigitを使用して、結果の 2 つのファイルとを結合しますpaste

    • paste alpha digit-d " "(タブの代わりにスペースを使用するように追加できます)

関連情報