如何在外壳中将字母行的文本与数字行合并?


10

我有一个文件,其内容如下:

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

等等...

我想将字母行与数字行匹配,所以它们是这样的:

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

有谁知道实现这一目标的简单方法?


您提到emacs..您是否正在寻找elisp解决方案,或者如何在emacs中运行shell脚本?
Peter.O 2012年

Answers:


3

一种使用方式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

有趣的是…… 删除前导和尾随空格的两条正则表达式替换行比使用反向引用和非贪婪的单行的运行速度快约1.6倍s/\A\s*(.*?)\s*\Z/\1/
Peter.O 2012年

4

在中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

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

或者,仅一步之遥,没有临时文件

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

最后sed一步删除空白行上的定界符,该定界符由paste...


3

对于emacs,使用矩形操作来剪切文本行并将其粘贴在数字行之前。


谢谢,但不是很适合15000+行!+ 1表示可行的想法,您需要代表:)
NWS 2012年

2

如果输入正确,

  1. 使用以下命令将输入​​分为字母输入和数字输入grep

    • grep "[[:alpha:]]\+" < file > alpha
    • grep "[[:digit:]]\+" < file > digit
  2. 加入两个生成的文件,alphadigit使用paste

    • paste alpha digit(您可以添加-d " "使其使用空格而不是制表符)

1
没有临时文件:paste <(grep "[[:alpha:]]\+" file) <(grep "[[:digit:]]\+" file)或具有单个进程替换:grep "[[:alpha:]]\+" file | paste - <(grep "[[:digit:]]\+" file)
jfg956 2012年

1

太糟糕的awk没有好的push / pop / unshift / shift功能。这是一个简短的Perl片段

perl -M5.010 -lne '
  given ($_) {
    when (/^[[:alpha:]]+$/) {push @alpha, $_}
    when (/^\d+$/) {say shift(@alpha), " ", $_}
    default {say}
  }
'

当我运行它时,它每组输出一个额外的(前导)空白行。
Peter.O 2012年

根据该default条款,将立即打印空白行,因此“ 1234”之前的空白将显示在“ AAAA”行之前。
格伦·杰克曼

0

提供带有文本的文件,尝试使用pr和处理替代语法,如下所示:

$ pr -mt <(grep -i "^[a-z]" file.txt) <(grep -i "^[0-9]" file.txt)
AAAA                    1234
BBBB                    5678
CCCC                    9012
DDDD                    3456
EEEE                    7890

您可以通过调整宽度-w9或通过删除空格sed "s/ //g"

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.