알파벳 줄의 텍스트를 쉘의 숫자 줄과 병합하는 방법은 무엇입니까?


10

다음과 같은 텍스트가있는 파일이 있습니다.

AAAA
BBBB
CCCC
DDDD

1234
5678
9012
3456

EEEE 

7890

기타...

그리고 나는 알파벳 라인을 숫자 라인과 일치시키기를 원합니다.

AAAA 1234 
BBBB 5678
CCCC 9012
DDDD 3456

EEEE 7890

누구나 이것을 달성하는 간단한 방법을 알고 있습니까?


당신은 emacs.. 당신은 elisp해결책 을 찾고 있습니까 , 아니면 emacs에서 쉘 스크립트를 실행하는 방법을 찾고 있습니까?
Peter.O

답변:


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

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

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

1

너무 나쁜 awk에는 좋은 푸시 / 팝 / 언 시프트 / 시프트 기능이 없습니다. 짧은 Perl 스 니펫이 있습니다.

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

내가 그것을 실행할 때, 그룹 당 여분의 (공행) 빈 줄을 출력합니다.
Peter.O

default절로 인해 빈 줄이 즉시 인쇄되므로 "1234"앞의 빈 줄이 "AAAA"줄 앞에 표시됩니다.
glenn jackman 10

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".

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.