programing

unix - 파일의 head 및 tail

batch 2023. 4. 11. 21:49
반응형

unix - 파일의 head 및 tail

txt 파일이 있다고 가정하면 파일의 상위 10줄과 하위 10줄을 동시에 표시하는 명령어는 무엇입니까?

즉, 파일의 길이가 200줄인 경우 1-10줄과 190-200줄을 한 번에 봅니다.

다음과 같이 간단하게 할 수 있습니다.

(head; tail) < file.txt

어떤 이유로든 파이프를 사용해야 하는 경우 다음과 같이 하십시오.

cat file.txt | (head; tail)

참고: 파일 내의 행 수가 많을 경우 중복된 행이 인쇄됩니다.txt는 기본 머리줄 + 기본 꼬리줄보다 작습니다.

ed는 는 입니다.standard text editor

$ echo -e '1+10,$-10d\n%p' | ed -s file.txt

순수 스트림(예: 명령어 출력)의 경우, 'tee'를 사용하여 스트림을 분기하고 스트림을 선두에 하나씩, 후미에 보낼 수 있습니다.여기에는 bash(+/dev/fd/N)의 '>'(목록) 기능을 사용해야 합니다.

( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )

또는 /dev/fd/N(또는 /dev/stderr)과 복잡한 리다이렉트 서브셸을 사용합니다.

( ( seq 1 100 | tee /dev/fd/2 | head 1>&3 ) 2>&1 | tail ) 3>&1
( ( seq 1 100 | tee /dev/stderr | head 1>&3 ) 2>&1 | tail ) 3>&1

(이들 중 어느 쪽도 csh 또는 tcsh에서는 동작하지 않습니다).

제어가 조금 더 나은 경우에는 다음 perl 명령을 사용할 수 있습니다.

COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
(sed -u 10q; echo ...; tail) < file.txt

입니다.(head;tail)작은 파일의 초기 버퍼 채우기 문제를 방지합니다.

J.F.를 기반으로 합니다. Sebastian의 코멘트:

cat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1

이렇게 하면 1개의 파이프에서 첫 번째 줄과 나머지 줄을 다르게 처리할 수 있으므로 CSV 데이터를 사용하는 데 유용합니다.

{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
N*2246

지금까지의 모든 사용 사례를 망라한 유일한 솔루션인 것 같은 이 솔루션을 완성하는 데 많은 시간이 걸렸습니다.

command | tee full.log | stdbuf -i0 -o0 -e0 awk -v offset=${MAX_LINES:-200} \
          '{
               if (NR <= offset) print;
               else {
                   a[NR] = $0;
                   delete a[NR-offset];
                   printf "." > "/dev/stderr"
                   }
           }
           END {
             print "" > "/dev/stderr";
             for(i=NR-offset+1 > offset ? NR-offset+1: offset+1 ;i<=NR;i++)
             { print a[i]}
           }'

기능 목록:

  • 헤드용 라이브 출력(테일용이 불가능함을 나타냅니다)
  • 외부 파일 사용 안 함
  • MAX_LINES 뒤에 있는 각 행에 대해 도트가 하나씩 표시되므로 장시간 실행되는 작업에 매우 유용합니다.
  • stderr의 프로그레스바.프로그레스 도트가 헤드+테일로부터 분리되어 있는 것을 확인합니다(stdout을 파이프 접속하는 경우에 매우 편리합니다).
  • 버퍼링(stdbuf)으로 인한 잘못된 로깅 순서를 방지합니다.
  • 총 라인 수가 헤드 + 테일보다 작을 경우 출력이 중복되지 않도록 합니다.

head -10 file.txt; tail -10 file.txt

그 외에 프로그램/대본을 직접 작성해야 합니다.

여기서 문제는 스트림 지향 프로그램이 파일의 길이를 미리 알 수 없다는 것입니다(실제 스트림일 경우 파일이 없을 수 있기 때문입니다).

★★★★★★★★★★★★★★★ 의 툴tail표시된 마지막 n개의 행을 버퍼링하고 스트림의 끝을 기다린 후 인쇄합니다.

이것을 1개의 커맨드로 실행하는 경우(오프셋으로 동작하도록 하고, 행이 겹치는 경우는 반복하지 말아 주세요)는, 이 동작을 에뮬레이트 할 필요가 있습니다.

이 awk를 사용해 보세요.

awk -v offset=10 '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' yourfile

와 같이, 렇렇해해 so해 sohead fiename_foo && tail filename_foo이 경우 . 파일 함수를 쓸 수

head_and_tail() {
    head $1 && tail $1
}

합니다.「 」 「 」 「 」head_and_tail filename_foo.

저는 이 해결책을 오랫동안 찾고 있었습니다.sed로 직접 시도했지만, 파일/스트림의 길이를 사전에 모르는 문제는 극복할 수 없었습니다.위의 모든 옵션 중에서 나는 Camille Goudesune의 awk 솔루션이 마음에 든다.그는 자신의 솔루션이 출력에 충분한 양의 데이터 세트를 가진 여분의 빈 행을 남겼다는 것을 메모했습니다.여기에서는, 여분의 라인을 삭제하는 그의 솔루션의 수정을 나타냅니다.

headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { a_count=0; for (i in a) {a_count++}; for (i=NR-a_count+1; i<=NR; i++) print a[i] }' ; }

file.ext의 첫 번째 10행, 마지막 10행:

cat file.ext | head -10 && cat file.ext | tail -10

파일의 마지막 10줄, 그리고 처음 10줄:

cat file.ext | tail -10 && cat file.ext | head -10

그런 다음 출력을 다른 곳에서도 파이핑할 수 있습니다.

(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program

이를 위해 간단한 파이썬 앱을 만들었습니다.https://gist.github.com/garyvdm/9970522

파일뿐만 아니라 파이프(스트림)도 처리합니다.

위의 아이디어를 바탕으로 작성(bash & zsh)

'모자'라는 가명을 쓰고

alias hat='(head -5 && echo "^^^------vvv" && tail -5) < '


hat large.sql

소비량은 적지만 단순하며 사용 사례의 99%에 적합합니다.

헤드 앤 테일

#!/usr/bin/env bash
COUNT=${1:-10}
IT=$(cat /dev/stdin)
echo "$IT" | head -n$COUNT
echo "..."
echo "$IT" | tail -n$COUNT

$ seq 100 | head_and_tail 4
1
2
3
4
...
97
98
99
100

「」를 사용하지 sed이업 사용 용용 용? ???

sed -n -e 1,+9p -e 190,+9p textfile.txt

파이프(스트리밍) 및 파일을 처리하려면 .bashrc 또는 .profile 파일에 다음을 추가합니다.

headtail() { awk -v offset="$1" '{ if (NR <= offset) print; else { a[NR] = $0; delete a[NR-offset] } } END { for (i=NR-offset+1; i<=NR; i++) print a[i] }' ; }

그러면 너는 할 수 있을 뿐만 아니라

headtail 10 < file.txt

하지만 또한

a.out | headtail 10

(은, 에서도, 일반적인 구(舊)와 , a.out | (head; tail)이전 회답자님 감사합니다.)

★★★★★★headtail 10 아니라, 이에요.headtail -10.

@Alexandra Zalcman의 명령어가 어떻게 동작하는지에 대한 @Samus_의 설명에 근거해, 이 변형은 행수를 세지 않고는, 꼬리가 어디에서 시작되는지를 신속히 찾아낼 수 없을 때에 편리합니다.

{ head; echo "####################\n...\n####################"; tail; } < file.txt

또는 20개 라인 이외의 다른 라인에서 작업을 시작할 경우 라인 수가 도움이 될 수 있습니다.

{ head -n 18; tail -n 14; } < file.txt | cat -n

파일의 처음 10줄과 마지막 10줄을 인쇄하려면 다음과 같이 하십시오.

cat <(head -n10 file.txt) <(tail -n10 file.txt) | less

sed -n "1,10p; $(( $(wc -l ${aFile} | grep -oE "^[[:digit:]]+")-9 )),\$p" "${aFile}"

메모: aFile 변수에는 파일의 전체 경로가 포함됩니다.

파일의 크기에 따라서는, 적극적으로 내용을 읽는 것은 바람직하지 않을 수 있습니다.그런 상황에서는 간단한 셸 스크립팅으로 충분하다고 생각합니다.

다음은 제가 분석하던 다수의 대용량 CSV 파일에 대해 최근에 이 문제를 해결한 방법입니다.

$ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done

그러면 각 파일의 처음 10줄과 마지막 10줄이 출력되며 파일 이름 및 줄임표도 출력됩니다.

하나의 대용량 파일에 대해 동일한 효과를 얻기 위해 다음을 실행할 수 있습니다.

$ head somefile.csv && echo ... && tail somefile.csv

저는 주로 여기서 제안하는 것을 바탕으로 몇 가지 실험을 더 했습니다.조금 작업한 후 다른 코멘트에서 다른 버전과 매우 유사한 것을 준비했지만 stdin 외에 여러 파일 arg를 사용하여 포맷하는 데 더 중점을 두고 있습니다.

이것은 스크립트로 잘 정리됩니다(잠정적으로).headtailgnu awk를 사용합니다.macO 에서는, 다음의 방법으로 인스톨 할 수 있습니다.brew install gawk.

파이핑된 콘텐츠 또는 파일 목록에서 인수로 작동할 수 있습니다.파일을 지정하면 파일명의 헤더, 선두N 행, 생략된 행 메이커, 테일N 행이 출력됩니다.머리와 꼬리가 겹치거나 일렬로 정렬될 경우 건너뛰기 마커가 포함되지 않으며 중복된 선이 표시되지 않습니다.

#!/bin/bash
headtail_awk() {
  N=10
  gawk -v "n=${N}" -- '\
  FNR == 1 && FILENAME != "-" {
    printf "\033[036m==> %s <==\033[0m\n", FILENAME;
  }
  # print head lines
  FNR <= n { print }
  # store lines in a circular buffer
  { a[FNR % n]=$0 }
  # print non-overlapping tail lines from circular buffer.
  ENDFILE {
    if ( FNR > 2 * n ) {
      printf "\033[0;36m>>> %s lines skipped <<<\033[0m\n", FNR - 2 * n
    }
    for (i=FNR-n+1;i<=FNR;i++) {
      if ( i > n) {
        print a[i % n]
      }
    }
  }
' "$@"
}
headtail_awk "$@"

N=10 라인 윈도우의 getopts 및/또는 향상된 기능을 독자들에게 연습용으로 남깁니다.

여러 파일의 샘플 출력(n=3):

$ headtail -n 3 /usr/share/dict/words /usr/share/dict/propernames
==> /usr/share/dict/words <==
A
a
aa
>>> 235880 lines skipped <<<
zythum
Zyzomys
Zyzzogeton
==> /usr/share/dict/propernames <==
Aaron
Adam
Adlai
>>> 1302 lines skipped <<<
Wolfgang
Woody
Yvonne

(head - 100) < source > 。txt > target.txt

(head - 100) <소스.txt 는, 송신원으로부터 최초의 100 행을 취득합니다.txt 파일 및 그 다음

taget.txt는 100 행을 target이라는 새로운 파일에 푸시합니다.txt

처음에는 이런 것이 작동해야 한다고 생각했습니다. 헤드 - 100 소스입니다.txt > target.txt에서 빈 파일을 반환했습니다.

언급URL : https://stackoverflow.com/questions/8624669/unix-head-and-tail-of-file

반응형