Sıkıldım, burada bir dosyayı kendi kendine nasıl birleştireceğiniz, çoğunlukla headbir koltuk değneği olarak kullanabileceğiniz birkaç yöntem daha var . Afedersiniz, eğer kendimi fazla açıklarsam, sadece bir şeyler söylemek istiyorum:
Varsayalım Nki kendi birleştirme işlemi yapmak ve dosyanızın isimlendirilmesi file.
Değişkenler:
linecount=$(<file wc -l)
total_repeats=$(echo "2^$N - 1" | bc) # obtained through the power of MATH
total_lines=$((linecount*(total_repeats+1)))
tmp=$(mktemp --suffix .concat.self)
Bir kopyası Verilen filedenilen file2, total_repeatskaç kez fileeklenecek gerekir file2aynı sanki yapmaya filekendisine birleştirilmiş edildi Nkez.
Bahsedilen MATH burada, az ya da çok: MATH (öz)
İlk dönem bilgisayar bilimi olayı oldu ama uzun zamandır bir indüksiyon kanıtı yaptım, bu yüzden üstesinden gelemem ... (ayrıca bu yineleme sınıfının olduğu da oldukça iyi biliniyor. 2^Loops)
POSIX
Posix olmayan birkaç şey kullanıyorum ancak bunlar zorunlu değil. Amaçlarım için:
yes() { while true; do echo "$1"; done; }
Oh, bunu sadece kullandım. Ah, bölüm zaten burada ...
Yöntemler
head linecount izleme ile.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Temp dosyası yok, kedi yok, henüz matematik bile yok, tüm neşe.
teeile MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
İşte ondan teeokuma fileama buna sürekli ekleme, bu yüzden headduruncaya kadar dosyayı tekrar okumaya devam edecek . MATH nedeniyle onu ne zaman durduracağımızı da biliyoruz . Sona doğru düştüğü için geçici bir dosya kullandım. Fazla çizgileri de filekesebilirsin.
eval, karanlığın efendisi!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Bu sadece genişler cat file file file ...ve ona göre değişir. $tmpDosya olmadan da yapabilirsiniz :
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
İkinci head"hileler" catarasına ortadaki bir adamı koyarak yazma işlemidir. Bir catbaşkasını catda kandırabilirsin ama bunun tutarsız davranışı var. Bunu dene:
test_double_cat() {
local Expected=0
local Got=0
local R=0
local file="$(mktemp --suffix .double.cat)"
for i in $(seq 1 100); do
printf "" > $file
echo "1" >> $file
echo "2" >> $file
echo "3" >> $file
Expected=$((3*$(<file wc -l)))
cat $file $file | cat >> $file
Got=$(<file wc -l)
[ "$Expected" = "$Got" ] && R="$((R+1))"
done
echo "Got it right $R/100"
rm $file
}
sed:
<file tr '\n' '\0' |
sed -e "s/.*/$(yes '\0' | head -n $total_repeats | tr -d '\n')/g" |
tr '\0' '\n' >> file
Kuvvetler sedbir çizgi olarak dosyanın tamamını okuma içine, hepsi bunun yakalar, o zaman o yapıştırır $total_repeatskaç kez.
Dosyanızda boş karakter varsa, bu elbette başarısız olacaktır. Orada olmadığını bildiğin birini seç.
find_missing_char() {
local file="${1:-/dev/stdin}"
firstbyte="$(<$file fold -w1 | od -An -tuC | sort -un | head -n 1)"
if [ ! "$firstbyte" = "0" ]; then
echo "\0"
else
printf "\\$(printf '%03o\t' $((firstbyte-1)) )"
fi
}
Hepsi bu kadar beyler, umarım bu keyfi cevap kimseyi rahatsız etmedi. Hepsini defalarca test ettim ama sadece iki yıllık bir kabuk kullanıcısıyım, bu yüzden sanırım bunu aklınızda bulundurun. Şimdi uyu ...
rm $tmp