Sizinle sed
şunları yapabilirsiniz:
sed '24q;1,5d;12,18d' <infile >outfile
... Muhtemelen daha etkili bir çözüm elde edilebilirdi head
. Don zaten bunun nasıl iyi çalışabileceğini gösterdi, ama ben de onunla oynuyorum. Bu özel durumu ele almak için yapabileceğiniz bir şey:
for n in 5 6 7 6
do head -n"$n" >&"$((1+n%2))"
done <infile >outfile 2>/dev/null
... yinelemenin değerinin çift ya da tek bir sayı olup olmadığına bağlı olarak head
ya outfile
da /dev/null
bu $n
sayıya 4 kez yazmayı gerektirir .
Daha genel durumlar için, bunu zaten sahip olduğum diğer şeylerden birlikte topladım:
somehead()(
### call it like:
### somehead -[repeat] [-][numlines]* <infile >outfile
set -e -- "${1#-}" "$@" #-e for arg validation
r=; cd -- "${TMP:-/tmp}" #go to tmp
dd bs=4096 of="$$$$" <&4 2>&3 & #dd <in >tmpfile &bg
until [ -s "$$$$" ]; do :; done #wait while tmpfile empty
exec <"$$$$" 4<&-; rm "$$$$" #<tmpfile; rm tmpfile
[ "$3${1}0" -ne "$3${2#?}0" ] || #validate args - chk $1
shift "$(((r=-${1:--1})||1))"; shift #shift 1||2
while [ "$(((r+=(_n=1))-1))" -ne 0 ] && #while ! $rptmax &&
IFS= read -r l && # ! EOF &&
printf "%.$(($1>0?${#l}+1:0))s" "$l # ? printf do
"; do for n do [ "${n#-}" -gt 0 ] || exit #args all -[nums>0]
head "-n$((${n#-}-_n))" >&"$((n>(_n=0)?1:3))" #head -n?$1 >?[+-]
done; done #done and done
) 4<&0 3>/dev/null #4<for dd 3>for head
Bu sizin gibi bir şey yapabilirsiniz:
seq 100 | somehead -1 -5 6 -7 6
... hangi baskı ...
6
7
8
9
10
11
19
20
21
22
23
24
İlk argümanının a ile başlayan bir tekrar sayısı -
veya başarısız olması durumunda sadece a -
. Bir sayım sağlanırsa, aşağıdaki bağımsız değişkenlerde belirtilen çizgi desenini belirtildiği kadar tekrar eder ve bunu yapar yapmaz durur.
Sonraki her bağımsız değişken için, yazılması gereken bir satır sayısını belirtmek için negatif bir tamsayıyı ve yazılması gereken /dev/null
bir satır sayısını belirtmek için pozitif bir tamsayıyı yorumlayacaktır stdout
.
Yukarıdaki örnekte, ilk 5 satırı /dev/null
, sonraki 6'dan stdout
sonraki sonraki 7'ye /dev/null
tekrar ve sonraki 6'ya tekrar yazdırır stdout
. Arglerinin sonuncusuna ulaşıp -1
tekrar sayımıyla tamamen döngüye girdikten sonra kapanır. İlk argüman olsaydı -2
, süreci bir kez daha ya da -
olabildiğince tekrar ederdi .
Her arg çevrimi için while
döngü bir kez işlenir. Her döngünün üstünde ilk satır stdin
kabuk değişkenine okunur $l
. while head </dev/null; do :; done
Süresiz olarak tekrarlanacağı için bu gereklidir - head
dosya sonuna geldiğinde geri dönüşünü gösterir. Bu nedenle EOF'a karşı kontrol , yalnızca ikinci argüman pozitif bir tamsayı olduğunda adanmış read
ve yeni bir satır printf
yazacaktır .$l
stdout
read
Kontrol döngüsü, bir az şey komplike bir döngü olarak adlandırılır hemen sonra, çünkü - bir for
bağımsız değişken yineler döngü 2-$#
de temsil edildiği gibi $n
, üst her okunması için while
döngü. Bu, her yinelemede ilk bağımsız değişkenin komut satırında belirtilen değerden biri tarafından azaltılması gerektiği, ancak diğerlerinin orijinal değerlerini koruması gerektiği ve böylece $_n
marker var değerinin değerinin her birinden çıkarılması gerektiği, ancak yalnızca ilk arg için 0'dan büyük bir değer.
Bu, işlevin ana döngüsünü oluşturur, ancak kodun büyük kısmı üsttedir ve işlevin giriş olarak bir boruyu temiz bir şekilde tamponlamasını sağlar. Bu, önce dd
bir parçayı 4k boyutta blok boyutlarında çıktıya bir tmp dosyasına kopyalamak için arka planı çağırarak çalışır . Daha sonra işlev, tek bir tam döngüyü bile neredeyse hiç tamamlamaması gereken bir tutma döngüsü oluşturur; yalnızca dd
işlevden önce dosyaya en az tek bir yazma işlemi yaptıktan sonra stdin'ini tmpfile ile bağlantılı bir dosya tanımlayıcıyla değiştirmesini sağlar ve daha sonra dosyayı derhalrm
. Bu, işlevin tuzak gerektirmeden veya temizleme için başka bir şekilde akışı güvenilir bir şekilde işlemesini sağlar - işlev fd'de iddia ettiği gibi serbest bırakılır yayınlanmaz, yalnızca adlandırılmış dosya sistemi bağlantısı zaten kaldırıldığı için tmpfile varlığını durduracaktır.
head
vetail
? Eğer öyleyse, çözümünüz yapabileceğiniz en iyi çözümdür. Başka programları kullanma izniniz varsased
veyaawk
daha iyi çözümlere izin verebilirseniz (yani daha az işlem çağrısı ile).