Cách chuyển đổi hai tệp ASCII được phân tách


-3

Đây là 2 vấn đề chuyển đổi tập tin văn bản được phân tách phổ biến mà tôi muốn tìm tập lệnh để thực hiện (Tôi không biết nếu awkhay perlnhất là cho các tác vụ này).

cshlà vỏ mặc định trên máy chủ Solaris 10 unix tôi, vì vậy giải pháp mà làm việc cho một trong hai cshhoặc shvỏ sẽ được ưa thích.

VẤN ĐỀ 1:

Tôi có 2 tệp ASCII được phân tách sau: File1.datFile2.dat

File1.dat (tệp bản đồ):

1|A  
2|B  
3|C  
4|D  
5|E  
6|F  
.  
.  
.  
26|Z  
27|Who  
28|What  
29|Where

File2.dat

Field1|Field2|Field3  
1|John|20120101  
3|Amy|20120103  
6|Larry|20120104  
3|Kevin|20120203  
8|Fred|20120623  
4|Mary|20120728  
26|Eric|20120819  
28|Larry|20120917

Tôi muốn sử dụng bản đồ được thể hiện File1.datđể chuyển đổi File2.datthành tệp thứ 3 File3.dattrông giống như sau. Về cơ bản, tôi đang sử dụng bản đồ trong File1.dat để tạo / điền một cột mới vào tệp của mình để cuối cùng, tệp được chuyển đổi mới có 4 cột, như sau:

File3.dat

Field1|Field2|Field3|Field4  
1|A|John|20120101  
3|C|Amy|20120103  
6|F|Larry|20120104  
3|C|Kevin|20120203  
8|H|Fred|20120623  
4|D|Mary|20120728  
26|Z|Eric|20120819  
28|What|Larry|20120917

VẤN ĐỀ 2:

Tôi muốn chỉ giữ bản ghi thứ nhất (trong một loạt các bản ghi được sắp xếp) của một họ các bản ghi có chung điểm chung [Trường 2, Trường 3, Trường4 có cùng giá trị trên các bản ghi]

Tôi có tệp được phân tách ban đầu sau đây File1.dat (15 bản ghi mỗi tệp có 4 Trường). Ở bên trái không phải là một phần của tệp, đây chỉ là Bản ghi # để chúng tôi có thể theo dõi những gì đang xảy ra.

File1.dat

    Field1|Field2|Field3|Field4
1.    20120227|Andy|101|34  
2.    20120315|Andy|101|34  
3.    20120415|Andy|101|36  
4.    20120417|Andy|103|37  
5.    20120417|Andy|103|37  
6.    20120227|Jane|101|34  
7.    20120315|Jane|101|34  
8.    20120415|Jane|101|36  
9.    20120417|Jane|103|37  
10.   20120417|Jane|103|37  
11.   20120227|Bob|101|34  
12.   20120315|Bob|101|34  
13.   20120415|Bob|101|36  
14.   20120417|Bob|103|37  
15.   20120417|Bob|103|37

Tôi muốn chuyển đổi 15 tệp bản ghi này ( File1.dat) thành tệp newfile ( File2.dat) trông giống như sau (chỉ giữ lại 9 bản ghi này).

Như bạn có thể thấy, nó lấy ra các bản ghi trùng lặp File1.dat, trong đó định nghĩa của bản ghi trùng lặp bằng [Field2 & Field3 & Field4 có các giá trị bằng nhau trên bất kỳ 2 hoặc nhiều bản ghi].

File2.dat

1.   20120227|Andy|101|34
3.   20120415|Andy|101|36
4.   20120417|Andy|103|37
6.   20120227|Jane|101|34
8.   20120415|Jane|101|36
9.   20120417|Jane|103|37
11.  20120227|Bob|101|34
13.  20120415|Bob|101|36
14.  20120417|Bob|103|37

Phần kết luận:

Xin vui lòng cho tôi biết nơi trong một mã giải pháp, nó giải quyết 2 điều sau đây:

a) Thực tế dấu phân cách trong các tệp của tôi là |ký tự ống
b) Phần nào của mã đề cập đến Field1, Field2, Field3, Field4, v.v.


3
Xin chào Andy và chào mừng đến với trang web Unix & Linux. Vui lòng xem lại Câu hỏi thường gặp . Điều này trái với chính sách của trang web là chỉ yêu cầu mọi người viết kịch bản và thực hiện công việc cho bạn. Chúng tôi ở đây để giúp không làm! Bạn đã cố gắng những gì cho đến nay? Nhìn vào câu hỏi của bạn, đây là những vấn đề rất cơ bản mà bạn sẽ có thể giải quyết bằng cách đơn giản.
slm

1
Rằng bạn sử dụng '|' vì dấu phân cách là khó xử, nhưng có thể giải quyết được (sử dụng "\ |" nếu được yêu cầu, có lẽ cần "\\ |" nếu nó đi qua một vòng xáo trộn trước đó). Đọc lên perl , bạn sẽ làm một chút về lập trình.
vonbrand

Theo nguyên tắc chung, trong thế giới * nix, bạn nên sử dụng TAB hoặc một không gian đơn giản làm dấu phân cách, nhiều chương trình sử dụng như mặc định. Trong mọi trường hợp, không bao giờ sử dụng |, nó chỉ làm cho cuộc sống của bạn khó khăn hơn.
terdon

Câu trả lời:


1

Giải pháp Perl:

Vấn đề 1.

File1.dat được đọc thành hàm băm, cột đầu tiên là khóa, cột thứ hai là giá trị. Sau đó, File2.dat được xử lý và giá trị từ hàm băm được chèn vào mảng biểu thị các giá trị trên một dòng theo khóa được lấy từ cột đầu tiên (trong Perl, zeroth).

#!/usr/bin/perl
use warnings;
use strict;

my %tab;

open my $F1, '<', 'File1.dat' or die $!;
while (<$F1>) {
    chomp;
    my ($key, $value) = split /\|/; # Here, the delimiter is mentioned.
    $tab{$key} = $value;
}

open my $F2, '<', 'File2.dat' or die $!;
while (<$F2>) {
    chomp;
    my @cols = split /\|/;
    splice @cols, 1, 0, $tab{$cols[0]};
    print join('|', @cols), "\n";
}

Bạn có thể nhận được đầu ra tương tự với các tiện ích tiêu chuẩn:

join -a2 -t'|' <(sort File1.dat) <(sort File2.dat) | sort -n

Vấn đề 2.

Hãy nhớ sự kết hợp của các lĩnh vực bạn đã thấy trong một hàm băm. Nếu sự kết hợp là mới, in dòng, nếu không thì không làm gì cả.

#!/usr/bin/perl
use warnings;
use strict;
use feature 'say';

my %seen;
while (<>) {
    chomp;
    my @fields = split /\|/, $_, 2;          # Only split into 2 fields.
    say unless exists $seen{$fields[1]};     # Do not print if already seen.
    undef $seen{$fields[1]};                 # Mark the key as seen.
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.