cat 출력에서 ​​첫 번째와 마지막 줄을 읽는 방법은 무엇입니까?


64

텍스트 파일이 있습니다. 작업-파일에서 첫 번째와 마지막 줄 가져 오기

$ cat file | grep -E "1|2|3|4" | commandtoprint

$ cat file
1
2
3
4
5

cat 출력없이 필요합니다 (1과 5 만).

~$ cat file | tee >(head -n 1) >(wc -l)
1
2
3
4
5
5
1

어색하고 더 짧은 해결책이있을 수 있습니다 ...


두 번째 예에서는 wc -l파일의 마지막 줄을 출력하는 것과 아무 관련이 없습니다.
David Richerby

답변:


115

sed 솔루션 :

sed -e 1b -e '$!d' file

stdinif 에서 읽을 때 (예 ps -ef:) :

ps -ef | sed -e 1b -e '$!d'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1931  1837  0 20:05 pts/0    00:00:00 sed -e 1b -e $!d

헤드 & 테일 솔루션 :

(head -n1 && tail -n1) <file

데이터가 명령에서 오는 경우 ( ps -ef) :

ps -ef 2>&1 | (head -n1 && tail -n1)
UID        PID  PPID  C STIME TTY          TIME CMD
root      2068  1837  0 20:13 pts/0    00:00:00 -bash

awk 솔루션 :

awk 'NR==1; END{print}' file

또한 파이프 예제 ps -ef:

ps -ef | awk 'NR==1; END{print}'
UID        PID  PPID  C STIME TTY          TIME CMD
root      1935  1837  0 20:07 pts/0    00:00:00 awk NR==1; END{print}

1
감사합니다! (head -n1 file;tail -n1 file)마지막 기호로 매우 큰 명령과 파이프를 가질 수 없기 때문에 가장 좋은 대답 입니다. 너무 | sed '1p;$!d'짧습니다.
dmgl 2016 년

영어 실력에 대해 죄송합니다. 이해가 안된다면-문제입니다-그것에 대해 알려 주시면 더 좋은 프레젠테이션을 준비 할 수 있습니다.
dmgl

7
head && tail정말 당신을 위해 작동 합니까 ? seq 10 | (head -n1 && tail -n1)인쇄 만합니다 1.
glenn jackman 2016 년

1
@DavidConrad는 혼돈의 말을 자세히 설명하기 위해 -e 1b-첫 번째 줄에서 sed 스크립트의 끝으로 분기하여 암시 적 "인쇄"가 발생합니다. 입력이 한 줄 길이이면 sed가 종료됩니다. 그렇지 않으면 마지막 행을 제외한 모든 행에 대해 삭제하십시오. 마지막 줄에서 암시적인 "인쇄"가 다시 발생합니다.
glenn jackman 2016 년

1
@ mikeserv : ;-) 기회가되면 확인하십시오. 한 줄에서는 출력에서 ​​두 배가되는 것을 효과적으로 방지하지만 여러 줄의 작업 사례에서는 마지막 줄을 유지합니다 sed. 적어도 GNU 4.2.2에서는 유지됩니다. 건배.
Cbhihe

23

sed -n '1p;$p' file.txt file.txt의 첫 번째와 마지막 줄을 인쇄합니다.


10
입력에 한 줄만 있으면 두 번 인쇄됩니다. sed -e 1b -e '$!d'원하지 않으면 선호 할 수 있습니다 .
Stéphane Chazelas

10

재미있는 순수한 Bash≥4 방법 :

cb() { (($1-1>0)) && unset "ary[$1-1]"; }
mapfile -t -C cb -c 1 ary < file

그런 다음 ary첫 번째 필드 (예 : index 0)가 첫 번째 행이고 file마지막 필드가 마지막 행인 배열 이 생성 file됩니다. 콜백 cb(어레이의 모든 라인을 스러 핑하려는 경우 선택 사항)은 메모리를 어지럽히 지 않도록 모든 중간 라인을 설정 해제합니다. 무료 부산물로 파일에 줄 수 (배열의 마지막 색인 +1)도 있습니다.

데모:

$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' {a..z})
$ declare -p ary
declare -a ary='([0]="a" [25]="z")'
$ # With only one line
$ mapfile -t -C cb -c 1 ary < <(printf '%s\n' "only one line")
$ declare -p ary
declare -a ary='([0]="only one line")'
$ # With an empty file
$ mapfile -t -C cb -c 1 ary < <(:)
declare -a ary='()'

7

으로 sed당신이 할 수 d라인을 elete 경우 NOT1 일 하나 AND NOT$t의 하나. AND 조건 을 결합하기 위해 조건과 구문을
사용하는 !데 사용 합니다 .NOTX{Y..}X Y

cmd | sed '1!{$!d;}'

또는 2nd 에서 lat까지 의 범위를 사용하고 위선을 $제외한 해당 범위의 모든 줄을 삭제할 수 있습니다 $.

cmd | sed '2,${$!d;}'

6

펄 사용하기 :

$ seq 10 |  perl -ne 'print if 1..1 or eof'
1
10

위의는를 seq 10통해 출력의 첫 번째 항목을 인쇄하는 if 1..1반면, or eof는 마지막 항목도 인쇄합니다.


3
이것이 어떻게 작동하는지 설명해 주시겠습니까? 그들이하는 일과 방법에 대한 설명없이 그러한 원 라이너 답변을 제공하지 마십시오.
terdon

1
무엇을해야 /etc abrt하고 yum.repos.d이 질문을 할 필요가?
drs

@ drs 나는 샘플 입력으로 'ls'를 사용하지 않도록 답변을 편집했습니다.
고인돌

1
@ dolmen : / etc에 대한 모든 참조를 억제하여 편집을 끝내는 것이 좋습니다. 나는 첫 번째 편집 후에 추가 된 것으로 생각하지만 대답이 전혀 의미가 없기 때문에 모두 동일합니다. 그냥 제안입니다.
Cbhihe

4

고양이없이 :

$ cat file |tee >(head -n1) >(tail -n1) >/dev/null
1
5

또는

$ (head -n1 file;tail -n1 file)
1
5

8
첫 번째 줄의 순서는 보장되지 않습니다.
Stéphane Chazelas

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