`꼬리`와`머리`에 대한 역 행동을 얻는 방법?


55

할 수있는 방법이 있나요 head/ tail문서 및 역 출력을 얻을은; 문서에 몇 줄이 있는지 모르기 때문에?

즉, foo.txt다른 문서에 추가 할 첫 두 줄을 제외한 모든 것을 얻고 싶습니다 .

답변:


57

이를 사용하여 처음 두 줄 을 제거 할 수 있습니다 .

tail -n +3 foo.txt

마지막 두 줄 을 제거합니다 .

head -n -2 foo.txt

(파일이 \n후자로 끝났다고 가정 )


단지의 표준 사용을 위해 좋아 tail하고 head이러한 작업은 파괴되지 않습니다. >out.txt출력을 새 파일로 리디렉션하려는 경우 사용하십시오 .

tail -n +3 foo.txt >out.txt

케이스가에 out.txt이미 존재하는,이 파일을 덮어 쓰게됩니다. 출력을에 추가 하려면 >>out.txt대신에 사용하십시오 .>out.txtout.txt


3
다시 "파일,"로 끝나는 경우 \n" .. 다음 과 같이 ( 음수 (GNU coreutils) 7.4 사용) ... 와 같이 아무것도-n -0 반환 하지 않는 모든 음의 정수에 대해 작동합니다 -n 0. 그러나 후행 \n이 있으면 -n -0인쇄합니다. 로가 기대 될 수있다 -즉. 전체 파일을 인쇄합니다. 따라서 0이 아닌 모든 음수 값에 대해서는 -0작동 합니다. 그러나 후행이 없으면 실패합니다\n
Peter.O

@fred : 정말로 이상하다… (여기 8.12와 동일).
Stéphane Gimenez

이 작업이 파괴적인가? 문서의 처음 두 줄의 역을 다른 것으로 복사하고 싶습니까?
chrisjlee

@Chris : 아니요. 단지 "표준 출력"으로 결과를 인쇄합니다.이 출력은 보통 터미널에 연결됩니다. 출력을 일부 파일로 리디렉션하는 방법에 대한 세부 정보를 추가했습니다.
Stéphane Gimenez

7
head -n -2POSIX와 호환 되지 않습니다 .
l0b0

9

첫 번째 N-1 회선을 제외한 모든 회선을 원하면 회선 tail수로 전화 하십시오 +N. (숫자는 1부터 시작하여 유지하려는 첫 번째 줄의 번호입니다. 즉, +1은 맨 위에서 시작을, +2는 한 줄을 건너 뛰는 등을 의미합니다).

tail -n +3 foo.txt >>other-document

마지막 N 줄을 건너 뛸 수있는 쉽고 휴대용 방법은 없습니다. GNU headhead -n +N의 대응으로 허용 tail -n +N합니다. 그렇지 않은 경우 tac(예 : GNU 또는 Busybox) 꼬리와 결합 할 수 있습니다.

tac | tail -n +3 | tac

이식 가능하게 awk 필터를 사용할 수 있습니다 (예상치 않음).

awk -vskip=2 '{
    lines[NR] = $0;
    if (NR > skip) print lines[NR-skip];
    delete lines[NR-skip];
}'

큰 파일에서 마지막 몇 줄을 제거하려면 잘라낼 조각의 바이트 오프셋을 결정한 다음로 잘라내기를 수행 할 수 있습니다 dd.

total=$(wc -c < /file/to/truncate)
chop=$(tail -n 42 /file/to/truncate | wc -c)
dd if=/dev/null of=/file/to/truncate seek=1 bs="$((total-chop))"

처음에 파일을 잘라낼 수는 없지만 거대한 파일의 처음 몇 줄을 제거해야 할 경우 내용을 옮길 수 있습니다 .


현대 리눅스와 같은 일부 시스템에서는 처음에 파일을 잘라내거나 (축소) 일반적으로 FS 블록 크기의 배수만큼만 (이 경우에는 실제로는 유용하지 않음) 수 있습니다.
Stéphane Chazelas 16:19에

3

로부터 tailman 페이지 (GNU tail, 즉) :

-n, --lines=K
   output the last K lines, instead of the last 10; or use -n +K to
   output lines starting with the Kth

따라서 다음은 첫 두 줄을 제외한 나머지 모두에 추가해야 somefile.txt합니다 anotherfile.txt.

tail --lines=+3 somefile.txt >> anotherfile.txt

3

첫 번째 n 줄을 제거하려면 GNU sed를 사용할 수 있습니다. 예를 들어 n = 2 인 경우

sed -n '1,2!p' input-file

!평균 "이 간격을 제외". 상상할 수 있듯이 더 복잡한 결과를 얻을 수 있습니다 (예 :

sed -n '3,5p;7p'

3,4,5,7 행이 표시됩니다. 주소 대신 정규식을 사용하면 더 많은 힘을 얻을 수 있습니다.

한계는 줄 번호를 미리 알아야한다는 것입니다.


1
왜 안돼 sed 1,2d? 일반적으로 단순할수록 좋습니다. 또한, 예제에서 GNU Sed에만 해당되는 것은 없습니다. 모든 명령 은 Sed의 표준 POSIX 기능을 사용합니다 .
와일드 카드

1

/ diff의 출력을 원본 파일과 비교 하고 동일한 것을 제거하여 역을 얻는 데 사용할 수 있습니다 .headtail

diff --unchanged-group-format='' foo.txt <(head -2 foo.txt)

1

tail -n +44 번째 줄 (처음 3 줄을 제외한 모든 줄)에서 시작하는 파일을 표준으로 출력 할 수는 있지만 해당 파일 head( head -n -3마지막 3 줄을 제외한 모든 줄)은 그렇지 않습니다.

다행히도, 당신은 할 것입니다 :

sed '$d' | sed '$d' | sed '$d'

또는:

sed -ne :1 -e '1,3{N;b1' -e '}' -e 'P;N;D'

( sed크기가 제한된 패턴 공간을 가진 일부 시스템에서는 큰 값으로 확장되지 않습니다 n).

또는:

awk 'NR>3 {print l[NR%3]}; {l[NR%3]=$0}'

1
{   head -n2 >/dev/null
    cat  >> other_document
}   <infile

경우 <infile정기적 인 lseek()-able 파일, 다음 네, 부디, 주시기 바랍니다. 위는 완전 POSIX 지원 구조입니다.


0

내 접근 방식은 Gilles와 비슷하지만 cat으로 파일을 반대로 바꾸고 head 명령으로 파일을 파이프합니다.

tac -r thefile.txt | thisfile.txt로 이동 (파일 대체)


0

당신의 필요를 분명히 이해하기를 바랍니다.

요청을 완료하는 몇 가지 방법이 있습니다.

tail -n$(expr $(cat /etc/passwd|wc -l) - 2) /etc/passwd

어디 / passwd 파일은 / etc 파일이

큰 파일이 있으면 두 번째 솔루션이 유용 할 수 있습니다.

my1stline=$(head -n1 /etc/passwd)
my2ndline=$(head -n2 /etc/passwd|grep -v "$my1stline")
cat /etc/passwd |grep -Ev "$my1stline|$my2ndline"

0

BSD 솔루션 (macOS) :

처음 두 줄을 제거하십시오.

tail -n $( echo "$(cat foo.txt | wc -l)-2" | bc )

마지막 두 줄을 제거하십시오.

head -n $( echo "$(cat foo.txt | wc -l)-2" | bc )

... 매우 우아하지는 않지만 작업을 완료합니다!

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.