Saya bosan jadi di sini ada beberapa metode tentang cara menggabungkan file untuk dirinya sendiri, kebanyakan dengan head
sebagai penopang. Maafkan saya jika saya menjelaskan sendiri, saya hanya suka mengatakan hal-hal: P
Dengan asumsi N
adalah jumlah rangkaian diri yang ingin Anda lakukan dan bahwa file Anda dinamai file
.
Variabel:
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)
Diberikan salinan yang file
dipanggil file2
, total_repeats
adalah berapa kali file
perlu ditambahkan file2
untuk membuatnya sama seperti jika file
digabungkan ke N
waktu itu sendiri .
Kata MATH ada di sini, kurang lebih: MATH (inti)
Ini hal ilmu komputer semester pertama tapi sudah lama sejak saya melakukan bukti induksi sehingga saya tidak bisa mengatasinya ... (juga kelas rekursi ini cukup terkenal 2^Loops
sehingga ada juga ....)
POSIX
Saya menggunakan beberapa hal non-posix tetapi mereka tidak penting. Untuk tujuan saya:
yes() { while true; do echo "$1"; done; }
Oh, saya hanya menggunakan itu. Oh well, bagian itu sudah ada di sini ...
Metode
head
dengan pelacakan linecount.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Tidak ada file temp, tidak ada kucing, belum terlalu banyak matematika, semua sukacita.
tee
dengan MATEMATIKA
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Berikut tee
adalah bacaan dari file
tetapi terus-menerus menambahkannya, sehingga akan terus membaca file di ulangi sampai head
berhenti. Dan kita tahu kapan harus menghentikannya karena MATEMATIKA . Appendenya lewat laut, jadi saya menggunakan file temp. Anda bisa memotong garis berlebih dari file
terlalu.
eval
, penguasa kegelapan!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Ini hanya memperluas cat file file file ...
dan mengevaluasinya. Anda juga dapat melakukannya tanpa $tmp
file:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
head
"Trik" kedua cat
dengan menempatkan perantara di antara itu dan operasi penulisan. Anda bisa menipu cat
dengan orang lain cat
juga tetapi itu memiliki perilaku yang tidak konsisten. Coba ini:
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
Memaksa sed
untuk membaca seluruh file sebagai satu baris, menangkap semua file, lalu menempelkannya $total_repeats
beberapa kali.
Tentu saja ini akan gagal jika Anda memiliki karakter nol di file Anda. Pilih satu yang Anda tahu tidak ada di sana.
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
}
Itu saja untuk sekarang para pemuda, saya harap jawaban sewenang-wenang ini tidak mengganggu siapa pun. Saya menguji mereka semua berkali-kali tapi saya hanya pengguna shell dua tahun jadi ingatlah itu saya kira. Sekarang tidur ...
rm $tmp