Köpek bash yardımcı programını uygulayın


10

dog birincisi yazılacak metin ve diğerleri keyfi olarak çok sayıda dosya olan rastgele sayıda argüman alan bir komut satırı yardımcı programıdır.

Yardımcı dogprogram metni bu dosyalar üzerinde eşit bölümlere böler. Geriye kalanlar varsa n, ilk ndosyalar ek bir bayt alır

dogaşağıdaki gibi olması gerektiği catgibi tersidir x.

$> dog x a.txt b.txt ...
$> cat a.txt b.txt ...
x$>

Nerede ...keyfi olarak birçok dosya olduğunu gösterir.

Bir örnek (12 bayt, 3 dosya, eşit olarak bölünebilir):

$> ./dog.py "Dogs vs Cats" a.txt b.txt c.txt
$> cat a.txt
Dogs$> cat b.txt
 vs $> cat c.txt
Cats$> cat a.txt b.txt c.txt
Dogs vs Cats$> 

Kalan bir örnek (13 bayt, 5 dosya, kalan 3):

9$>./dog.py "0123456789abc" a.txt b.txt c.txt d.txt e.txt
$> cat a.txt
012$> cat b.txt
345$> cat c.txt
678$> cat d.txt
9a$> cat e.txt
bc$> cat a.txt b.txt c.txt d.txt e.txt
0123456789abc$>

Bu ima edilir, ancak sadece iki kez kontrol etmek için: 1) Argümanların komut satırı üzerinden gelmesi gerekiyor mu? 2) Her zaman dosyalara çıktı vermek zorunda mıyız?
Sp3000

@ Sp3000 evet, 1 ve 2
Caridorc

1
@DigitalTrauma zaten bir cevap var, bir kural değişikliği ile geçersiz
kıldığım

2
Son zamanlarda bu siteden bazı garip UNIX yardımcı programları hakkında bilgi ediniyorum (tac, dog, ...).
kirbyfan64sos

1
@ kirbyfan64sos ve Caridorc: tacgerçek .
DLosc

Yanıtlar:


4

Pyth - 12 bayt

.wMC,cl.zz.z

Yerleşik split işlevini kullanır ve ardından yazma işlevinde splat-map kullanır. Çevrimiçi çalışmıyor.


2

Python - 181 bayt

import sys
a=sys.argv
l=len
d=a[2:]
s=a[1]
n,r=divmod(l(s),l(d))
p=0
for i in range(l(d)):
    with open(d[i],'w') as f:
        o=n+int(i<=n)
        f.write(s[p:p+o])
        p+=o

1

PHP, 107 bayt

Golf kodu:

for($i=1;++$i<$argc;fputs(fopen($argv[$i],w),substr($s=$argv[1],($i-2)*$l=ceil(strlen($s)/($argc-2)),$l)));

Ayrıntılı kod:

$len = ceil(strlen($argv[1])/($argc - 2));
for ($i = 2; $i < $argc; $i ++) {
    $fh = fopen($argv[$i], 'w');
    fputs($fh, substr($argv[1], ($i - 2) * $len, $len));
    fclose($fh);          // omitted in the golfed version
}

0

Saf bash: 97

s=$1;shift;for((l=${#s}/$#,m=${#s}-l*$#,i=1;i<=$#;p+=q,i++)){
printf "${s:p:q=i>m?l:l+1}">${!i};}

Bir fonksiyon olarak: ( p=sadece ikinci çalıştırma için gereklidir)

dog() { p=
    s=$1;shift;for((l=${#s}/$#,m=${#s}-l*$#,i=1;i<=$#;p+=q,i++)){
    printf "${s:p:q=i>m?l:l+1}">${!i};}
}

Testler

$> rm *
$> dog "Dogs vs Cats" a.txt b.txt c.txt
$> ls -l
total 12
-rw-r--r-- 1 user user 4 May 13 22:09 a.txt
-rw-r--r-- 1 user user 4 May 13 22:09 b.txt
-rw-r--r-- 1 user user 4 May 13 22:09 c.txt
$> cat {a,b,c}.txt;echo
Dogs vs Cats
$> 

Tüm dosyalar 4 byte len'dir ve doğru sırada birleştirilir, "Dogs vs Cats" içerir .

$> rm *
$> dog "$(printf "%s" {0..9} {a..c})" {a..e}.txt 
$> ls -l
total 20
-rw-r--r-- 1 user user 3 May 13 22:09 a.txt
-rw-r--r-- 1 user user 3 May 13 22:09 b.txt
-rw-r--r-- 1 user user 3 May 13 22:09 c.txt
-rw-r--r-- 1 user user 2 May 13 22:09 d.txt
-rw-r--r-- 1 user user 2 May 13 22:09 e.txt
$> cat *;echo
0123456789abc
$> 

İlk dosyalar 3 bayt len ​​ve son 2 harf, alfabetik sıra ile "0123456789abc" içeriyor .

Açıklama (ungolfing):

Eğer vurursanız: declare -f dog, cevap verecektir:

$> declare -f dog
dog () 
{ 
    p=;
    s=$1;
    shift;
    for ((l=${#s}/$#,m=${#s}-l*$#,i=1; i<=$#; p+=q,i++))
    do
        printf "${s:p:q=i>m?l:l+1}" > ${!i};
    done
}

Bu yazılabilir:

dog2 () 
{ 
    position=0;
    string=$1;
    shift;
    partLen=$((${#string}/$#));
    oneMore=$((${#string}-partLen*$#));
    for ((i=1; i<=$#; i++))
    do
        if ((i<=oneMore)); then
            partQuant=$((partLen+1));
        else
            partQuant=$partLen;
        fi;
        printf "${string:position:partQuant}" > ${!i};
        ((position+=partQuant));
    done
}

0

Yakut, 93 87 bayt

Komut satırı bağımsız değişkenlerini kullanarak tam program.

Eğer s.slice!dizeyi değiştirmek için kullanabilseydim s[c..-1], bunu kullanmak yerine bunu yapardım , ama Ruby önce çoğaltmadan argv'den dizeleri değiştirmenize izin vermez

s,*t=$*
d,r=s.size.divmod t.size
t.map{|e|open(e,?w)<<s[0,c=(0>r-=1)?d:d+1];s=s[c..-1]}
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.