파일을 읽을 때 특정 필드를 선택하고 Unix bash의 다른 파일과 비교하시겠습니까?

파일을 읽을 때 특정 필드를 선택하고 Unix bash의 다른 파일과 비교하시겠습니까?

a, b, c, d, e 열이 포함된 CSV 파일과 z 열이 포함된 다른 파일이 있습니다. 첫 번째 파일에서 한 줄씩 읽는 동안 c와 d 필드만 필요하고 두 번째 파일의 d와 z를 비교하려고 합니다.

z는 변수이고 의미는 입니다 for i in catfileb do ....... 이제 d가 z와 같으면 z가 표시되고, 다르면 항상 "pin"이 표시됩니다. 그러나 z가 가장 길거나 가장 작은 경우 "lon" 또는 "sma"가 표시됩니다.

파일 1:

a b c d e
1 2 2 3 3
3 4 6 5 9
4 5 0 9 9

파일 b:

z
3
1
8

그래서 c, d, z는 변수이므로 두 개의 루프를 생각했습니다. 파일을 한 줄씩 읽고 c와 d를 가져온 다음 z와 비교합니다.

답변1

file b한 줄을 in의 해당 줄과 비교하고 싶다고 가정하면 file a(즉, 두 파일의 줄 수가 동일하고 한 줄씩 비교하는 경우) Perl 스크립트를 사용하여 이 작업을 수행할 수 있습니다.

#!/usr/bin/perl
$file_a = "/path/to/file_a";
$file_b = "/path/to/file_b";
open $fa,'<',$file_a or die "Failed to open file $file_a: $!\n";
open $fb,'<',$file_b or die "Failed to open file $file_b: $!\n";
@file_a = <$fa>;
@file_b = <$fb>;
close $fa;
close $fb;
for (0..$#file_a){
    ($col_c,$col_d) = (split / /,$file_a[$_])[2,3];
    $col_z = $file_b[$_];
    $to_display = "$col_c $col_d";
    if($col_z eq $col_d){
        $to_display .= " $col_z";
    }
    else{
        $to_display .= " pin";
        if ($col_z gt $col_c and $col_z gt $col_d ){
            $to_display .= " lon";
        }
        elsif($col_z lt $col_c and $col_z lt $col_d) {
            $to_display .= " sma";
        }
    }
    print "$to_display\n";
}

위의 파일을 ( /path/to/myscript및 실제 위치를 수정한 후)로 저장한 다음 실행 가능하게 만들고 마지막으로 호출합니다.file_afile_bchmod +x /path/to/myscript$ /path/to/myscript

답변2

내가 댓글에서 말했듯이, 당신이 무엇을 원하는지 완전히 확신할 수 없습니다. 당신은 항상 필드를 인쇄 c하고 d비교하고 싶어하는 것 같습니다.오직 d그리고 z. 그렇다면 아래 솔루션이 작동합니다.

$ paste a b | awk '{print $3,$4,$6}' | head -n 1; paste a b | tail -n +2 |
   while read a b c d e z; do 
    echo -n "$c $d"; 
    if [ "$d" -lt "$z" ]; then 
      echo "pin sma"; 
    elif [ "$d" -gt "$z" ]; then 
      echo "pin lon"; 
    else echo $z; 
    fi; 
   done 

제공한 예제 파일을 실행하면 다음이 제공됩니다.

c d z
2 33
6 5pin lon
0 9pin lon

설명하다

산술 비교를 수행하려고 하므로 헤더로 인해 스크립트가 중단됩니다. 그러나 최종 출력에는 포함하고 싶을 것 같습니다. 먼저 인쇄합니다.

paste a b | awk '{print $3,$4,$6}' | head -n 1;

이제 헤더를 건너뛰고 나머지 필드를 처리하겠습니다. 그래서 우리는paste헤더( tail -n +2)를 건너뛰고 필드를 처리하여 파일을 다시 봅니다.

관련 정보