Sıkıldım, burada bir dosyayı kendi kendine nasıl birleştireceğiniz, çoğunlukla head
bir 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 N
ki 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 file
denilen file2
, total_repeats
kaç kez file
eklenecek gerekir file2
aynı sanki yapmaya file
kendisine birleştirilmiş edildi N
kez.
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.
tee
ile MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
İşte ondan tee
okuma file
ama buna sürekli ekleme, bu yüzden head
duruncaya 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 file
kesebilirsin.
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. $tmp
Dosya olmadan da yapabilirsiniz :
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
İkinci head
"hileler" cat
arasına ortadaki bir adamı koyarak yazma işlemidir. Bir cat
başkasını cat
da 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 sed
bir çizgi olarak dosyanın tamamını okuma içine, hepsi bunun yakalar, o zaman o yapıştırır $total_repeats
kaç 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