Cat çıkışından ilk ve son satır nasıl okunur?


64

Metin dosyam var. Görev - dosyadan ilk ve son satırı alın

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

$ cat file
1
2
3
4
5

Cat çıkışı olmadan buna ihtiyacınız var (sadece 1 ve 5).

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

Belki awk ve daha kısa bir çözüm var ...


İkinci örnekte, wc -lbir dosyanın son satırının çıktısıyla ilgisi yoktur.
David Richerby

Yanıtlar:


115

sed Çözüm:

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

Eğer stdinböyle bir şey olursa okur (örneğin 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

baş ve kuyruk Çözüm:

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

Bir komuttan veri geldiğinde ( 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 Çözümü:

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

Ve ayrıca borulu örnek 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
Teşekkür ederim! En iyi cevap bu çünkü (head -n1 file;tail -n1 file)son sembol olarak çok büyük bir komuta ve pipom var. Çok | sed '1p;$!d'kısa.
dmgl

İngilizcem için özür dilerim, eğer beni anlamıyorsan - bu benim sorunum - anlat bana ve senin için daha iyi sunum hazırlarım.
dmgl

7
head && tailGerçekten senin için çalışıyor mu ? sadece seq 10 | (head -n1 && tail -n1)yazdırır 1.
glenn jackman

1
@DavidConrad, kaosun ne dediğine dikkat çekmek için -e 1b- ilk satırda, baştaki "baskının" gerçekleştiği noktadaki betiğin sonuna kadar dallanın . Giriş sadece bir satır uzunluğunda ise sed biter. Aksi takdirde, sonuncusu dışındaki tüm satırlar için silin. Son satırda, örtük "yazdırma" tekrar olur.
glenn jackman

1
@mikeserv: ;-) bir şansınız olduğunda kontrol edin. Tek bir hat üzerinde, çıktıda iki katına çıkmasını etkili bir şekilde önler, ancak çok hatlı bir çalışma durumunda, sadece son satırı korur ... en azından GNU sed4.2.2. Şerefe.
Cbhihe

23

sed -n '1p;$p' file.txt file.txt 'in ilk ve son satırını yazdıracaktır.


10
Girdide yalnızca bir satır varsa, iki kere yazdırılacağını unutmayın. Bunu sed -e 1b -e '$!d'istemiyorsanız tercih edebilirsiniz .
Stéphane Chazelas

10

Komik bir saf Bash≥4 yolu:

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

Bundan sonra , ilk satırı ary(yani, dizini içeren 0) ilk satırı fileve son alanı da son satırı içeren bir dizi elde edersiniz file. Geri arama cb(dizideki tüm çizgileri sıkıştırmak istiyorsanız isteğe bağlı), tüm ara çizgileri belleğin dağılmaması için ayarlar. Ücretsiz bir yan ürün olarak, dosyadaki satır sayısına da sahip olacaksınız (dizinin son dizini olarak + 1).

Demo:

$ 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

Eğer st değil ve la değil ise hatları ile elete sedolabilir . Kullanım için (olumsuzladığı) bir durum ve birleştirmek için yapı VE koşullar:d1$
!NOTX{Y..}X Y

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

ya da - 2nd'den la - ye kadar olan bir aralığı kullanabilir $ve o satırdaki tüm satırları silebilirsiniz $:

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

6

Perl kullanımı:

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

Yukarıda çıkışında ilk öğeyi yazdırır seq 10aracılığıyla if 1..1iken, or eofirade de son öğeyi yazdırmak.


3
Bunun nasıl çalıştığını açıklayabilir misiniz? Lütfen ne tür bir cevap verdiklerini ve ne yaptıklarını açıklamadan kaçının.
terdon

1
ne yapmak /etc abrtve yum.repos.dbu soruyu yapmak zorunda?
drs

@ drs Örnek giriş olarak 'ls' kullanmaktan kaçınmak için cevabı değiştirdim.
dolmen

1
@dolmen: / etc dizinine yapılan tüm başvuruları bastırarak düzenlemeyi bitirmek iyi bir fikir olabilir. Sanırım ilk düzenleme yapıldıktan sonra böyle bir şey eklendi, fakat hepsi aynı, cevabın geçerli olduğu gibi bir anlamı yok. Sadece bir öneri.
Cbhihe

4

Kedi olmadan:

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

veya

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

8
İlki, hatların sırası garanti edilmez.
Stéphane Chazelas

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.