저는 데이터베이스를 통해 바나나를 생산하는 농부와 그들의 주소를 알아내려고 합니다.
내 데이터는 다음과 같습니다.
- farmer1 address1 apple1,banana-green,orange-5
- farmer2 address2 orange-unriped6,apple-red,banana-canarvon,peach-sweet
- farmer3 address3 peach-blacklisted,orange-ok,lime-unriped
- farmer4 address4 banana-humungous,orange-meh,watermelon-amazing,vegetables-fresh
시도해 grep
보았지만 주요 세부 정보를 텍스트 파일로 인쇄할 수 없습니다. 파일을 cut
다음 awk
과 같이 만들고 싶습니다.
- farmer1 address1 banana-green
- farmer2 address2 banana-canarvon
- farmer4 address4 banana-humongous
누구든지 도와줄 수 있나요?
그래서 Cas의 스크립트(Cas에게 감사드립니다!)를 사용한 후 필요한 정보를 추출할 수 있었습니다. 완벽했습니다! 그러나 필요한 정보 목록이 포함된 텍스트 파일이 있고 전체 목록(약 400개 항목)에 대해 이 프로세스를 반복하고 싶습니다. 목록을 처리하기 위해 스크립트를 수정하려고 시도했지만 잘못하고 있습니다. "실행"되는 것처럼 보이지만 아무것도 인쇄하지 않습니다.
#! /usr/bin/perl -a -n
open( GENEFILE, "ActinGenesENST.txt") or die "$!";
open( VARFILE, "Actin.ENSTvars.txt") or die "$!";
open( OUTPUTFILE, "test.txt") or die "!";
print "Extracting Genes\n";
while (<GENEFILE>) {
if (/VARFILE/) {
@produce=grep(/VARFILE/,split(/,/,$F[9])) ;
print OUTPUTFILE join("\t",@F[0 .. 8],join(",",@produce)),"\n";
}
}
- 내 "농부 목록"은 VARFILE에 있습니다.
- 내 "과일 목록"은 GENEFILE에 있습니다.
- TEST.TXT에 반환 값을 인쇄하고 싶습니다.
답변1
샘플 데이터를 라는 파일에 넣고 farmer.txt
다음 Perl 스크립트를 실행했습니다.
#! /usr/bin/perl -a -n
if (/banana/) {
@produce=grep(/banana/,split(/,/,$F[2])) ;
print join("\t",@F[0 .. 1],join(",",@produce)),"\n";
}
다음과 같은 출력이 생성되었습니다.
$ ./bananas.pl farmer.txt
farmer1 address1 banana-green
farmer2 address2 banana-canarvon
farmer4 address4 banana-humungous
입력에 "banana"가 포함된 각 줄에 대해 세 번째 필드를 $F[2]
@product라는 목록으로 쉼표로 구분하고 perl grep()
함수를 사용하여 바나나라는 단어가 포함된 요소만 유지합니다.
그런 다음 입력과 동일한 형식으로 인쇄합니다.
농부가 두 가지 이상의 바나나 유형을 생산하는 경우 이 스크립트는 모든 바나나를 표시합니다.
다음은 여러 "과일"("fruitlist.txt"에 포함됨)을 인쇄하는 스크립트 버전입니다.
#! /usr/bin/perl
use strict;
my $fruitlist='fruitlist.txt';
open(FRUITS,"<",$fruitlist) || die "couldn't open $fruitlist: $!\n";
while (<FRUITS>) {
chomp ;
my $fruit = $_;
print "$fruit\n---\n";
foreach my $file (@ARGV) {
open(FILE,"<",$file) || die "couldn't open $file: $!\n";
while(<FILE>) {
my @F=split(/\t/);
if (/$fruit/) {
my @produce=grep(/$fruit/,split(/,/,$F[2])) ;
print join("\t",@F[0 .. 1],join(",",@produce)),"\n";
}
}
close(FILE);
print "\n";
}
};
close(FRUITS);
나는 perl -a
(awk와 유사한) 모드를 포기하고 파일을 명시적으로 열고 내용을 @F 필드 배열로 분할했습니다. 왜냐하면 Fruitlist에 대해 입력 파일(예: farmer.txt)을 여러 번 다시 열어야 하기 때문입니다. 각 항목의 .txt.
두 개의 행(바나나 및 사과)이 포함된 경우 fruitlist.txt
스크립트는 다음 출력을 생성합니다.
$ ./multifruit.pl farmer.txt
banana
---
farmer1 address1 banana-green
farmer2 address2 banana-canarvon
farmer4 address4 banana-humungous
apple
---
farmer1 address1 apple1
farmer2 address2 apple-red
답변2
게시한 명령을 사용하여(죄송합니다. 변경했습니다 cut
) sed
다음 해결책을 얻었습니다.
cat your_file|sed 's/ /,/g'|awk -F, '{for (i=1;i<=NF;i++) {if (index(tolower($i),"banana")) {print $1,$2,$i}}}'
먼저, 동일한 필드 구분 기호로 모든 필드를 구분할 수 있도록 공백을 변경했습니다(따라서 awk 명령이 더 쉽습니다). 그 후에 awk
바나나를 잘 추출할 수 있습니다. 나는 농부당 바나나가 하나만 있을 수 있다고 가정하지만, 필요에 맞게 awk를 쉽게 수정할 수 있습니다.