결과:

결과:

다음과 같은 여러 열이 포함된 텍스트 파일이 있습니다.

 1 102.0184 109.5487 107.3716
 2 100.2430 107.5874 108.7558
 3 103.9029 105.7406 106.9046
 4 102.7495 108.1275 104.4731
 5 102.8825 105.6664 107.2141
 6 104.5323 108.8850 106.0267
 7 103.0479 107.3056 105.5108
 8 101.2433 108.6113 107.2551
 9 104.4821 108.4339 105.9864
 10 101.5879 106.3859 102.825

그런 다음 두 번째 열과 같이 다음과 같이 필터링합니다.

awk '$2<104 {print $1,$2}' file.txt 

이것을 얻었습니다:

1   102.0184
2   100.2430
3   103.9029
4   102.7495
5   102.8825
7   103.0479
8   101.2433
10  101.5879

첫 번째 열의 연속된 범위를 모두 다른 파일로 인쇄하고 싶으므로 이 예에서는 세 개의 출력 파일이 있습니다.

file_1-5.tmp
1   102.0184
2   100.2430
3   103.9029
4   102.7495
5   102.8825
file_7-8.tmp
7   103.0479
8   101.2433
file_10.tmp
10  101.5879

어떻게 해야 하나요? 파일의 모든 열에 대해 이 루틴을 어떻게 확장할 수 있나요? 나는 이 문제를 여러 파일에 적용하고 싶기 때문에 이 문제에 대한 일반적인 해결책(이 예제에 제공된 특정 범위에 의존하지 않음)이 있기를 바랍니다.

답변1

한 줄 awk명령:

awk -v P=-1 '$2<104 {if ($1>P+1)N=$1;P=$1;print $1,$2>"file"N".tmp"}'

결과 제공 (파일 이름이 마음에 들지 않는 경우)

==> file1.tmp <==
1   102.0184
2   100.2430
3   103.9029
4   102.7495
5   102.8825

==> file7.tmp <==
7 103.0479
8 101.2433

==> file10.tmp <==
10 101.5879

답변2

아래는 awk프로그램입니다. 매개변수에 제공된 열과 임계값을 사용할 수 있습니다.

awk -v column=2 -v threshold=104 '
    function save() { if (lines != "") print lines >"file_" first "-" last ".txt" }

    ! ($column < threshold) {
        save()
        first = last = lines = ""
        next
    }

    { 
        if (first == "") first = $1
        last = $1
        lines = lines $1 OFS $column ORS
    }

    END { save() }
'

연속된 행은 저장될 때까지 메모리에 남아 있습니다. 수억 개의 연속 행이 있는 경우 이 솔루션을 적용해야 합니다(각 행을 임시 파일에 저장한 다음 연속 블록의 마지막 행에 도달하면 이름을 바꿉니다).

답변3

awk '{$0 = $2 < 104 ? NR : RS}1' inputfile |
sed -Ee '
   $aq
   /./,/^$/!d;/./H;$ba;/^$/ba;d;:a
   g;s/.//;s/\n.*\n|\n/,/;x;s/.*//;x
   s/(.*),(.*)/&w file_\1_\2.tmp/
   /,/!s/.*/&w file_&.tmp/
' | ed -s inputfile -

여기서는 도구를 사용합니다 awk/sed/ed. Awk먼저 104보다 작은 모든 줄에 대해 줄 번호를 생성합니다. 다른 줄의 경우 빈 줄을 인쇄합니다. 그런 다음 Sed비어 있지 않은 줄부터 다음 빈 줄까지의 줄 범위를 살펴보세요. 그리고 행 번호를 보유에 저장하십시오. 이제 n, m 또는 일반 n의 두 가지 유형의 범위를 찾을 수 있습니다. 이를 사용하여 ed이러한 범위를 각각 n, mw file_n_m.tmp 및 file_n.tmp로 변환하는 명령 세트를 작성합니다 . 그런 다음 ed는 동적으로 생성된 이 ed 스크립트를 사용하여 입력 파일을 즉시 처리하고 해당 행을 .tmp 파일에 배치합니다.

작업을 수행하는 한 가지 방법은 다음과 같습니다 Perl.

perl -lane '
   BEGIN { $fmt = sprintf q[%s%%s\n%s], (chr 39)x2; }
   if ( $F[1] < 104 ) {
      push @A, "@F[0,1]";
      if ( eof ) {
         my $f = join $", q<printf>, $fmt, map(qq[\"$_\"], @A), q[>], (( ! defined $a ) ? qq[file_${.}.tmp] : qq[file_${a}_${.}.tmp]);
         system("$f");
      } else { $a //= $.; }
   } else {
      next if ! defined $a;
      $b //= $.-1;
      my $f = join $", q<printf>, $fmt, map(qq[\"$_\"], @A), q[>], (( $a == $b ) ? qq[file_$b.tmp] : qq[file_${a}_$b.tmp]);
      system("$f");
      ($a, $b, @A) = (undef)x2;
   }
' yourfile

결과:

file_1_5.tmp file_7_8.tmp file_10.tmp입력이 주어지면 다음 3 개의 파일이 생성됩니다.

% 더 많은 file_1_5.tmp file_7_8.tmp file_10.tmp

::::::::::::::
file_1_5.tmp
::::::::::::::
1 102.0184
2 100.2430
3 103.9029
4 102.7495
5 102.8825
::::::::::::::
file_7_8.tmp
::::::::::::::
7 103.0479
8 101.2433
::::::::::::::
file_10.tmp
::::::::::::::
10 101.5879

설명하다:

먼저 기본 최상위 아이디어: 두 번째 필드가 숫자 104 뒤에 있는지 여부에 세심한 주의를 기울입니다. 이 경우 이전 범위를 인쇄해야 함을 의미합니다. 단일 길이 범위의 경우 이를 반영하도록 파일 이름이 수정됩니다.

eof또 다른 경우는 현재 범위($F[1] < 104)를 누적하는 경우입니다. 이 작업을 수행하는 동안 히트하면 이제 범위를 인쇄해야 한다는 점을 명심하세요 .

추신: 이 system명령은 동적으로 생성된 형식을 사용하여 동적으로 생성되며 해당 데이터는 첫 번째 및 두 번째 필드이며 마지막으로 범위를 기반으로 .tmp 파일 이름이 생성됩니다.

$a$b범위 시작/끝 줄 번호입니다 . 그들의 주정부는 우리에게 올바른 결정을 내리도록 알려줄 것입니다.

관련 정보