2012-06-25 27 views
5

Tôi có một tệp văn bản bắt đầu bằng mã chữ số 9 chữ số và kết thúc bằng mã khóa học gồm 5 chữ số.Hợp nhất 2 dòng vào một

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, 
Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 

Có một số mục nhập có ngắt dòng như minh họa trong ví dụ 3 ở trên. tôi cần phải hợp nhất dòng thứ 3 và thứ 4 vào một giống như 1 và dòng 2, để tôi có thể dễ dàng sử dụng lệnh như grep, awk, vv

Cập nhật:

câu trả lời của Kevin dường như không làm việc.

cat todel.txt 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 

cat todel.txt | perl -ne 'chomp; if (/^\d{9}/) { print "\n$_" } else { print "$_\n" }' 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531ege of, 
+0

awk '/^[0-9] /,/[0-9] $ /' # không hoạt động – shantanuo

Trả lời

1

Liên quan đến các dòng được chia nhỏ và chỉ có một phân chia trên mỗi dòng phân tách.

Được sửa đổi để chấp nhận đầu vào bằng dòng mới CRLF của Windows hoặc * nix LF. nhưng lưu ý rằng đầu ra là một * nix \n

sed -nr 's/\r?$// # allow for '\r\n' newlines 
     /^([0-9]{9}) .* ([0-9]{5})$/{p;b} 
     /^([0-9]{9}) /{h;b} 
     /([0-9]{5})$/{x;G; s/\n//; p}' 

hay, ngắn hơn, nhưng có lẽ ít có thể đọc:

sed -nr 's/\r?$//; /^([0-9]{9}) /{/ ([0-9]{5})$/{p;b};h;b};/ ([0-9]{5})$/{x;G; s/\n//; p}' 

Tôi hy vọng rằng một trong những đầu tiên là nhanh hơn, bởi vì kiểm tra thường xuyên nhất (đối với đầy đủ các dòng) chỉ liên quan đến một regex duy nhất, trong khi kịch bản thứ hai (ngắn hơn), cần hai bài kiểm tra regex để kiểm tra thường xuyên nhất.

Đây là đầu ra tôi nhận được; sử dụng GNU sed 4.2.1

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering,Pune 61220 enter code hereMechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
+0

# Không hoạt động với các ví dụ được hiển thị trong câu hỏi. ## sed phiên bản 4.1.5 – shantanuo

+0

Điều đó thật kỳ lạ; nó hoạt động cho tôi (tôi đã thêm đầu ra và phiên bản sed để trả lời) .. Nó có đưa ra một thông báo lỗi, hoặc không tạo ra kết quả mong muốn? (có thể nó không xử lý mở rộng regex swithc '-r' ??) –

+0

Tệp có bình thường * nix' \ n' dòng mới (so với Windows '\ r \ n' hoặc thậm chí là Mac cũ' \ r')? Tôi đã gặp phải sự cố trước đây, khi xử lý các tệp được tạo bằng Windows. –

0

lẽ cố gắng để loại bỏ tất cả các dòng-chia xảy ra sau dấu phẩy, như vậy:

perl -i -pe 's/,\n/,/g' file.txt 

có lẽ bạn muốn cho phép không gian sau dấu phẩy:

perl -i -pe 's/(,\s*)\n/$1/g' file.txt 
+1

ngắt dòng không cần thiết xảy ra sau dấu phẩy. – shantanuo

1

Giả sử bạn dữ liệu nằm trong "file.txt", đây là bản quét có thể xếp các đường lại với nhau:

cat file.txt | perl -ne 'chomp; if (/^\d{9}/) { print "\n$_" } else { print "$_\n" }' 

Điều này giả định rằng tất cả các bản ghi hợp lệ bắt đầu bằng số có 9 chữ số. Các "chomp" loại bỏ dòng mới ban đầu, và mô hình quyết định nơi một dòng mới sẽ xuất hiện trong đầu ra.

1

Điều này có thể làm việc cho bạn:

sed ':a;$!N;/ [0-9]\{5\}\n[0-9]\{9\} /!s/\n//;ta;P;D' file 

Giải thích:

  • Nếu dòng không kết thúc trong một không gian tiếp theo năm chữ số tiếp theo chín chữ số và sau đó một khoảng trắng, xóa dòng mới.

EDIT:

Test data:

cat <<\! >/tmp/codel.txt 
> 112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
> Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
> ! 
sed ':a;$!N;/\s[0-9]\{5\}\n[0-9]\{9\}\s/!s/\n//;ta;P;D' /tmp/codel.txt 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
sed ':a;$!N;/\s[0-9]\{5\}\n[0-9]\{9\}\s/!s/\n//;ta;P;D' /tmp/{codel.txt,codel.txt,codel.txt} 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of,Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 
+0

Dường như không hoạt động với ví dụ thứ hai ở trên. Đã cập nhật câu hỏi. – shantanuo

+0

@shantanuo được thử nghiệm bằng cách sử dụng dữ liệu mới của bạn (xem EDIT) có vẻ tốt với tôi. – potong

0

thử này

sed '/^[0-9]\{9\}/{h;};/^[0-9]\{9\}/!{x;G;s/\n//g;}' test | grep -E '[0-9]{5}$' 
+0

Không hoạt động với tệp mẫu đầu tiên được hiển thị trong câu hỏi. – shantanuo

0
awk '! ($1 ~ /^[[:digit:]]/) {$0 = save " " $0} $1 ~ /^[[:digit:]]/ {save = $0} $NF ~ /[[:digit:]]$/ {print}' inputfile 
+0

Điều này làm việc với ví dụ thứ hai nhưng không phải với ví dụ đầu tiên. – shantanuo

+0

@shantanuo: Cái đầu tiên là cái tôi đã thử nghiệm và nó hoạt động tốt cho tôi. Ngoài ra, khi tôi ống nó để 'wc -l' tôi nhận được 3. –

+0

Awk 3.1.5 trả về 4 dòng thay vì 3 – shantanuo

0
cat todel.txt |awk 'BEGIN {i=0} {first[i]=$1; lines[i++] = $0;} END {for (x=0; x<i; x++) { if (x==(i - 1) || (first[x + 1] ~ /^[0-9]+$/ && length(first[x + 1])==9)) {printf("%s: %s\n", x, lines[x]);} else {printf("%s: %s%s\n", x, lines[x], lines[x + 1]); x++;} } }' 
0

này làm việc với các dữ liệu bao gồm thiết lập bằng cách giả hồ sơ hợp lệ kết thúc w thứ i năm chữ số:

use Modern::Perl; 

my $data = do{local $/; <DATA>}; 
$data =~ s/([^\d]{5})\n/$1 /sg; 
say $data; 


__DATA__ 
512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, 
Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, 
Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 93531 

Output:

512161000 EN5121 K. K. Jorge Institute of Engineering Education and Research, Nashik 61220 Mechanical Engineering [Second Shift] XOPENH 1 116 16978 
517261123 EN5172 R. C. Rustom Institute of Technology, Shirpur 61220 Mechanical Engineering [Second Shift] YOPENH 1 100 29555 
617561234 EN6175 abc xyz Education Trust, abc xyz College of Engineering, Pune 61220 Mechanical Engineering [Second Shift] ZOPENH 2 105 25017 
112724510 EN1127 Jagadambha Bahuuddeshiya Gramin Vikas Sanstha's Jagdambha College of, Engineering and Technology, Yavatmal 24510 Computer Engineering LSCO 1 55 935315 
+0

regex của bạn' s/([^ \ d] {5}) \ n/$ 1/sg; 'nên là' s/^ (\ d {9}. *?) (\ n) [^ \ d {5} \ n]/$ 1/gm; 'bởi vì nếu dòng tìm thấy số ** có 5 chữ số trong giữa dòng ** và nếu ngắt dòng có (đó là thực sự là trường hợp) sau đó regex của bạn sẽ thất bại.Với ví dụ: xem xét vi phạm tại '61220' trong dòng thứ hai. –

Các vấn đề liên quan