참조 마스터 파일에 지정된 필드|순서에 따라 파이프로 구분된 여러 텍스트 파일의 데이터(제목 및 세부 정보)를 재정렬하고 쉘 스크립트를 사용하여 단일 출력 파일을 생성하고 싶습니다. 아래 코드가 있지만 예상대로 작동하지 않습니다. while 루프는 마스터에서 열의 순서를 가져와 다시 정렬합니다. 그러나 고려해야 할 다음과 같은 기능이 있습니다.쉘 스크립트/awk에서 솔루션 찾기.
참조 마스터 파일과 비교하여 입력 파일에 누락되거나 새 열이 있을 수 있습니다. 참조 마스터 파일의 순서는 나중에 변경될 수 있으며 열은 어느 위치에서나 추가되거나 제거될 수 있습니다. 여러 입력 파일을 허용합니다.
입력 파일 A 예시:
Name|Amount|Vehicle|City|Visits|Indicator
Jack|123.22|Volkswagen|Altamonte|1|Y
Sam|23.1|Audi||3|N
|21.4|Ford|NewYork||Y
입력 파일 B 예시:
Suffix|Name|Visits|Vehicle|State|Indicator|City|Gender
Mr|Jack|1|Volkswagen|NJ|Y|Hoboken|M
Mr|Rob|6|Buick||N|Stamford|
기본 파일을 참조하십시오.
상태|1
도시|2
차량|3
성별|4
이름|5
수량|6
결과물 파일:
State|City|Vehicle|Gender|Name|Amount
|Altamonte|Volkswagen||Jack|123.22
||Audi||Sam|23.1
|NewYork|Ford|||21.4
NJ|Hoboken|Volkswagen|M|Jack|
|Stamford|Buick||Rob|
쉘 스크립트:
/*Comment::Reads the input column names and assign number based on order for*/
/*Comment::each column in the input file.*/
cat infile.out | head -1 | tr -s '|' '\n' | cat -n > infile_tmp.out
rm -f final.out
/*Comment:compare the master file column names with input file column names and
/*Comment:get the column number from master file*/
while read line; do
touch final.out
vChkClmn=`echo $line | cut -d "|" -f1`
vMasterClm=`grep -i $vChkClmn infile_tmp.out | cut -d " " -f1`
echo "$vMasterClm" >> final.out
done < master_file.out
rm -f final_master_list.out
echo `cat final.out` | sed 's/[^ ]* */\$&/g' | sed 's/ /\,/g' > final_master_list.out
vOrder=`cat final_master_list.out`
echo "Value of order is $vOrder"
awk -F\| '{print '$vOrder'}' OFS=\| infile.out
답변1
#!/usr/bin/perl
use strict;
my $master = shift;
open(M,"<","$master") || die "couldn't open $master:$!\n";
chomp(my @master = split(/\|/,<M>));
close(M);
print join("|",@master),"\n";
my @fields=();
while (<>) {
if ($. == 1) {
chomp(@fields = split /\|/);
next;
};
chomp(my @row = split/\|/);
my @out = ();
foreach my $m (@master) {
my $o='';
for (my $i=0; $i < $#row; $i++) {
if ($fields[$i] eq $m) {
$o = $row[$i];
};
}
push @out, $o;
};
print join("|",@out),"\n";
} continue {
close ARGV if eof; # reset the line counter after each input file
}
이는 참조 마스터 파일을 읽습니다(여기서~ 해야 하다명령줄의 첫 번째 인수)를 필드 이름(@master)이 포함된 배열로 분할합니다.
그런 다음 나머지 파일 이름 매개변수를 모두 읽고 다음을 수행합니다.
- 파일의 첫 번째 줄인 경우 줄을 배열로 분할하여 필드 헤더를 가져옵니다.
@fields
- 그렇지 않으면 행을 배열로 분할
@row
하고 @master 및 의 각 요소를 반복합니다@row
. 그 자리에서이름행 요소 중 하나가 @master의 요소와 일치하고 필드의 요소를 추가합니다.값출력 배열(@out)에 추가하고, 그렇지 않으면 빈 문자열을 추가합니다. @out
문자로 연결된 배열을 인쇄합니다|
.- 배열
@out
은 각 입력 라인에서 비어 있도록 재설정됩니다.
예를 들어 다른 이름으로 저장하고 rearrange.pl
실행 가능하게 만들고 chmod +x rearrange.pl
다음과 같이 실행합니다.
$ ./rearrange.pl master.txt input1.txt input2.txt
State|City|Vehicle|Gender|Name|Amount
|Altamonte|Volkswagen||Jack|123.22
||Audi||Sam|23.1
|NewYork|Ford|||21.4
NJ|Hoboken|Volkswagen||Jack|
|Stamford|Buick||Rob|
참고: 이는 두 개의 입력 파일에만 국한되지 않습니다. 한 번에 원하는 만큼의 입력 파일을 처리할 수 있습니다. 두 가지 제한사항만 있습니다.
기본 참조 파일(예
master.txt
: )~ 해야 하다명령줄의 첫 번째 매개변수입니다.입력 파일이 하나 이상 있어야 합니다.또는입력 파일은 스크립트로 파이프되어야 합니다.
참고: 하나의 파일만 입력할 수 있습니다.관로- 여러 파일이 파이프로 연결된 경우 스크립트는 어떤 줄이 헤더 줄이고 어떤 줄이 데이터 줄인지 알 수 없습니다.