제 주변에도 하나 있어요20pathtofiles.in
파일이 다른 폴더에 있는 경우 whichlists 라는 별도의 파일을 만들었습니다.길정보:
/home/users/gray_wolf/unix/File_1.tsv
/home/users/gray_wolf/unix/File_2.tsv
.
.
.
각 파일에는 대략적인 내용이 포함되어 있습니다.11 목록에 대한100,000 좋아요. 예:
파일 1:
Chromosome begin end .....
chr1 1000 2000
chr1 2000 3000
chr1 4000 5000
chr1 5000 6000
chr1 10000 12000
chr1 12000 13000
파일_2:
Chromosome begin end .....
chr1 1000 2000
chr1 4000 5000
chr1 5000 6000
chr1 6000 7000
chr1 10000 12000
chr1 13000 14000
최종 필수 파일 형식:
Chromosome begin end Column5 column8
chr1 1000 2000 File1,File2,File3... File1,File2,File3...
chr1 2000 3000 File1,File2(0),File3 File1,File2(0),File3...
chr1 4000 5000 File1,File2,File3... File1,File2,File3...
chr1 5000 6000 File1,File2,File3... File1,File2,File3...
chr1 6000 7000 File1,File2,File3... File1,File2,File3...
chr1 10000 12000 File1,File2,File3... File1,File2,File3...
chr1 12000 13000 File1,File2,File3... File1,File2,File3...
chr1 13000 14000 File1(0),File2,File3... File1(0),File2,File3...
pathtofile.in
내가 이것을 다음과 같이 전달할 때 :script.sh
./script.sh < pathtofile.in
...스크립트는 주어진 파일을 읽고 pathtofiles.in
출력 해야 합니다.5- 열 탭으로 구분된 목록입니다. 첫 번째삼출력 열은 다음과 같아야 합니다.삼 목록각 파일의결합된. 이것4출력 열은 해당 행이어야 합니다.5쉼표로 구분된 모든 입력 파일의 열( 과 동일한 순서 pathtofiles.in
)입니다. 이것5출력 열은 해당 행이어야 합니다.8쉼표로 구분된 모든 입력 파일의 열입니다.
특정 입력 행에 열이 누락된 경우8, (또는 열5), 해당 위치에 "(0)"을 출력합니다.
나는 열을 개별적으로 자르고반죽/가입하다기능을 수행하지만 각 파일마다 줄 수가 다르기 때문에 순서가 잘못됩니다. 어떻게 사용하나요?앗또는 아래에서 실행되는 다른 명령세게 때리다?
미리 감사드립니다.
~엠
답변1
간단한 해결책: paste
세 개의 파일을 함께 넣고 필요한 열을 가져옵니다.
paste -d' ' file1 file2 file3 |\
awk 'BEGIN { FS = " +" } { NR ==1} { printf "%-10s%-7s%-7s %-12s %-12s\n" $1,$2,$3,$6,$7 } { NR >=2 } { printf "%-10s%-7s%-7s %s,%s%s %s%s%s\n" $1,$2,$3,$6,$7,$8,$9,$10,$11 } '
이는 파일 및 출력 형식 기본 설정에 따라 채택되어야 합니다. 설명하다:
1) paste -d' '
-> 공백을 구분 기호로 사용하여 트리 파일을 수직으로 병합합니다 -d
.
2) 파이프로 연결 하고 가독성을 위해 awk
새 줄에 명령을 계속합니다 .|\
2.1) BEGIN { FS = " +" }
- 다음 모두에 대해 하나 이상의 (+) 공백을 필드 구분 기호로 사용하십시오.
2.2) 첫 번째 줄에 { NR ==1}
1,2,3,6,7( $1,$2 ...
) 필드를 다음 형식으로 인쇄합니다(큰따옴표로 묶음).
%-10s
10자 길이의 문자열이 수정되었습니다(나머지는 공백으로 채워지고 왼쪽 정렬됨).
같은 길이의 7자 두 배, 공백 2개, 12자 긴 문자열, 공백 2개, 12자 문자열입니다. \n
끝에 새 줄을 추가하십시오.
(섹션에서 확인 { printf "%-10s%-7s%-7s %-12s %-12s\n" $1,$2,$3,$6,$7 }
)
2.2) 데이터: 두 번째 행부터 { NR >=2 }
시작하여 열을 인쇄합니다 . $1,$2,$3,$6,$7,$8,$9,$10,$11
형식은 다음과 같습니다.%-10s%-7s%-7s %s,%s,%s %s,%s,%s\n
위와 유사하지만 이제 예를 들어 열 6,7,8은 임의 길이이며 쉼표로 구분됩니다.%s,%s,%s
답변2
모든 입력 파일을 동시에 열 수 있는 프로그램이 필요합니다. 구문이 awk
있으므로 that 또는 perl이 좋은 선택이 될 것입니다. getline <file
또는 당신이 알고 있는 다른 고급 언어.
이를 위해 저는 Perl을 선택하겠습니다. 가지다http://www.bioperl.org/유전자 서열 데이터 파일 형식을 처리하기 위해 특별히 설계된 Perl 모듈을 사용합니다.
생각보다 복잡할 수도 있다는 걸 깨닫고 중간에 포기했습니다. 입력 파일 중 하나가 다른 파일과 다른 열 2/3 값을 갖는 일반적인 경우를 처리하려면 다방향 diff 유형 알고리즘을 수행해야 합니다. 찾고 있는 시작/끝 쌍과 일치하는 항목을 찾을 때까지 그 줄을 계속 읽을 수는 없습니다. 왜냐하면 그것이 존재하지 않을 수도 있기 때문입니다.
따라서 가장 좋은 방법은 우선순위 대기열이나 정렬된 입력을 받는 것입니다. 각 파일에 대해 대기열에 삽입한 줄이 현재 파일 처리를 시작하기 전에 줄 뒤에 있을 때까지 읽습니다. (또는 방금 읽은 줄이 pqueue의 새로운 꼬리가 될 때까지).
파일이 한 번에 메모리에 쉽게 들어갈 수 있다면 연관 배열(column2:column3으로 인덱싱됨)을 사용하여 출력을 작성하면 코딩이 더 쉬워집니다. 그러면 우선 순위 대기열이 필요하지 않으며 다음에 어떤 파일을 진행할지 알아낼 필요도 없습니다.
이것은 지금까지 내 코드입니다. 순서가 잘못된 상황을 처리하거나 병합하지 않고 입력 라인을 반복합니다. 나는 이것이 합리적인 스택 교환 답변 범위보다 크다는 것을 깨달았을 때 중단했지만 이것이 시작을 제공할 수 있습니다.
#!/usr/bin/perl -w
my @f = @ARGV; # list of files to process
sub getfields($) {
my $file = $_[0];
my $ln = <$file> or return (); # sentinel for EOF
my @fl = split ' ', $ln, 9;
return ( $fl[0], $fl[1], $fl[2], $fl[4], $fl[7] );
}
# open each filename in @f, storing the file handles in @f.
foreach (@f) {
open $_, '<', $_ or die "opening $_: $!";
}
my $newdata = 0;
do {
$newdata = 0;
foreach my $fd (@f) {
my @fl = getfields($fd);
next if ! (@fl); # end of file on $fd. TODO: take it out of @f?
$newdata = 1;
print join("|", @fl), "\n"; # debug
}
} while ($newdata); # done when all files are EOF