Bir txt dosyanız olduğunu varsayalım, aynı anda dosyanın ilk 10 satırını ve alt 10 satırını görüntüleme komutu nedir?
yani dosya 200 satır uzunluğundaysa, 1-10 ve 190-200 satırlarını tek seferde görüntüleyin.
Bir txt dosyanız olduğunu varsayalım, aynı anda dosyanın ilk 10 satırını ve alt 10 satırını görüntüleme komutu nedir?
yani dosya 200 satır uzunluğundaysa, 1-10 ve 190-200 satırlarını tek seferde görüntüleyin.
Yanıtlar:
Basitçe şunları yapabilirsiniz:
(head; tail) < file.txt
Ve herhangi bir nedenle boru kullanmanız gerekiyorsa, o zaman şöyle:
cat file.txt | (head; tail)
Not: file.txt dosyasındaki satır sayısı varsayılan head satırlarından + varsayılan kuyruk satırlarından daha küçükse yinelenen satırları yazdıracaktır.
head
ilk 10 satırını tükettikten sonra akışın kuyruğu verir . (Bunu head < file.txt; tail < file.txt
20'den az satır içeren bir dosyada karşılaştırın ). Akılda tutulması gereken çok küçük bir nokta. (Ama yine de + 1.)
head
yalnızca ilk 10 satırını görüntülerken , 10. satır sonunu bulmak için daha fazlasını tüketmediğiless
ve görüntülenecek daha az giriş bırakmadığı garanti edilmez .
seq 100 | (head; tail)
bana sadece ilk 10 rakamı veriyor. Sadece çok daha büyük girdi boyutunda (gibi seq 2000
) kuyruk bir miktar girdi alır.
Saf bir akış için (örneğin bir komuttan çıktı), akışı çatallamak ve bir akışı başa diğerini kuyruğa göndermek için 'tee' kullanabilirsiniz. Bu, bash (+ / dev / fd / N) '> (liste)' özelliğinin kullanılmasını gerektirir:
( COMMAND | tee /dev/fd/3 | head ) 3> >( tail )
veya / dev / fd / N (veya / dev / stderr) artı karmaşık yeniden yönlendirmeli alt kabuklar kullanarak:
( ( 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
(Bunların hiçbiri csh veya tcsh'de çalışmaz.)
Biraz daha iyi kontrole sahip bir şey için bu perl komutunu kullanabilirsiniz:
COMMAND | perl -e 'my $size = 10; my @buf = (); while (<>) { print if $. <= $size; push(@buf, $_); if ( @buf > $size ) { shift(@buf); } } print "------\n"; print @buf;'
COMMAND | { tee >(head >&2) | tail; } |& other_commands
cat >/dev/null
düzeltir:COMMAND | { tee >(head >&2; cat >/dev/null) | tail; } |& other_commands
head
ve tail
komutlar: \ ...
head -10 file.txt; tail -10 file.txt
Bunun dışında kendi programınızı / betiğinizi yazmanız gerekecek.
cat
ve / head
veya tail
kullandım, onları ayrı ayrı kullanabileceğimi bilmek güzel!
{ head file; tail file; } | prog
( küme ayraçları arasındaki boşluk ve sondaki noktalı virgül gereklidir)
Dayanarak JF Sebastian'ın comment :
cat file | { tee >(head >&3; cat >/dev/null) | tail; } 3>&1
Bu şekilde, ilk satırı ve geri kalanını tek bir boruda farklı şekilde işleyebilirsiniz; bu, CSV verileriyle çalışmak için kullanışlıdır:
{ echo N; seq 3;} | { tee >(head -n1 | sed 's/$/*2/' >&3; cat >/dev/null) | tail -n+2 | awk '{print $1*2}'; } 3>&1
N * 2 2 4 6
Buradaki sorun, akış yönelimli programların dosyanın uzunluğunu önceden bilmemesidir (çünkü gerçek bir akışsa bir tane olmayabilir).
tail
Görülen son n satırı arabelleğe alma gibi araçlar ve akışın sonunu bekler, ardından yazdırır.
Bunu tek bir komutta yapmak istiyorsanız (ve herhangi bir ofset ile çalışmasını istiyorsanız ve üst üste binerse satırları tekrarlamayın) bahsettiğim bu davranışı taklit etmelisiniz.
bunu deneyin 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
a.out | awk -v ...
Tüm kullanım durumlarını kapsayan tek çözüm gibi görünen bu çözüme ulaşmak çok zaman aldı (şimdiye kadar):
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]}
}'
Özellik listesi:
Bir süredir bu çözümü arıyordum. Sed ile kendim denedim, ancak önceden dosya / akışın uzunluğunu bilmeme sorunu aşılamazdı. Yukarıdaki tüm seçenekler arasında Camille Goudeseune'un awk çözümünü beğendim. Çözümünün çıktıda yeterince küçük bir veri kümesiyle fazladan boş satırlar bıraktığını not etti. Burada, fazladan çizgileri ortadan kaldıran çözümünün bir değişikliğini sunuyorum.
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] }' ; }
Eh, onları her zaman birbirine zincirleyebilirsiniz. Öyle gibi
head fiename_foo && tail filename_foo
. Bu yeterli değilse, .profile dosyanıza veya kullandığınız herhangi bir giriş dosyasına kendinize bir bash işlevi yazabilirsiniz:
head_and_tail() {
head $1 && tail $1
}
Ve daha sonra istemi senin kabuğundan çağırmak: head_and_tail filename_foo
.
File.ext'in ilk 10 satırı, ardından son 10 satırı:
cat file.ext | head -10 && cat file.ext | tail -10
Dosyanın son 10 satırı, ardından ilk 10:
cat file.ext | tail -10 && cat file.ext | head -10
Daha sonra çıktıyı başka bir yere de aktarabilirsiniz:
(cat file.ext | head -10 && cat file.ext | tail -10 ) | your_program
tail
ve head
takma-ing bunu veya bir fonksiyonu.
Bunu yapmak için basit bir python uygulaması yazdım: https://gist.github.com/garyvdm/9970522
Dosyaları olduğu kadar boruları (akışları) da işler.
Dosyaları olduğu kadar boruları (akışları) da işlemek için bunu .bashrc veya .profile dosyanıza ekleyin:
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] }' ; }
O zaman sadece yapamazsın
headtail 10 < file.txt
Ayrıca
a.out | headtail 10
(Bu a.out | (head; tail)
, eski düzeyin aksine, 10 giriş uzunluğunu aştığında hala sahte boş satırlar ekler . Teşekkürler, önceki yanıtlayanlar.)
Not: headtail 10
hayır headtail -10
.
@ Samus_'un burada @Aleksandra Zalcman'ın komutunun nasıl çalıştığı hakkında açıkladığı şeye dayanarak, bu varyasyon, satırları saymadan kuyruğun nerede başladığını hızlıca anlayamadığınızda kullanışlıdır.
{ head; echo "####################\n...\n####################"; tail; } < file.txt
Ya da 20 satır dışında bir şeyle çalışmaya başlarsanız, satır sayısı yardımcı olabilir.
{ head -n 18; tail -n 14; } < file.txt | cat -n
Bir dosyanın ilk 10 ve son 10 satırını yazdırmak için şunu deneyebilirsiniz:
cat <(head -n10 file.txt) <(tail -n10 file.txt) | less
sed -n "1,10p; $(( $(wc -l ${aFile} | grep -oE "^[[:digit:]]+")-9 )),\$p" "${aFile}"
NOT : aFile değişkeni dosyanın tam yolunu içerir .
Dosyanın boyutuna bağlı olarak, içeriğini aktif olarak okumanın istenmeyebileceğini söyleyebilirim. Bu durumda, bazı basit kabuk komut dosyalarının yeterli olacağını düşünüyorum.
Son zamanlarda analiz ettiğim çok büyük CSV dosyaları için bunu şu şekilde ele aldım:
$ for file in *.csv; do echo "### ${file}" && head ${file} && echo ... && tail ${file} && echo; done
Bu, her dosyanın ilk 10 satırını ve son 10 satırını yazdırırken, aynı zamanda dosya adını ve öncesinde ve sonrasında bazı üç nokta yazdırır.
Tek bir büyük dosya için, aynı etki için aşağıdakileri çalıştırabilirsiniz:
$ head somefile.csv && echo ... && tail somefile.csv
Standart kullanır, ancak basittir ve kullanım durumlarının% 99'u için çalışır
#!/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