Мені нудно, ось ось ще кілька методів, як об'єднати файл у себе, в основному, headяк милицю. Вибачте, якщо я переосмислив себе, я просто люблю говорити: P
Якщо припустити, Nце кількість самозв'язків, які ви хочете зробити, і ваш файл названий file.
Змінні:
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)
З огляду на копію fileвиклику file2, total_repeatsскільки разів fileпотрібно було б додати, щоб file2вона була такою ж, як якщо б вона fileбула приєднана до себе Nразів.
Сказаний MATH тут, більш-менш: MATH (суть)
Це речі з інформатики першого семестру, але минуло певний час, коли я зробив довідку про індукцію, тому не можу перебороти це ... (також цей клас рекурсії досить добре відомий, щоб 2^Loopsтак було і там).
POSIX
Я використовую декілька не-позитивних речей, але вони не є істотними. Для моїх цілей:
yes() { while true; do echo "$1"; done; }
О, я лише цим користувався. Ну добре, розділ вже тут ...
Методи
head з відстеженням лінійних ліній.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Ні тимчасового файлу, ні кішки, ні навіть занадто багато математики, вся радість.
teeз MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Тут teeчитається з, fileале постійно додається до нього, тож він продовжує читати файл повторенням, поки не headзупинить його. І ми знаємо, коли це зупинити через МАТ . Додаток додається за борт, тому я використовував тимчасовий файл. Ви можете також обрізати зайві лінії file.
eval, володар темряви!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Це просто розширюється cat file file file ...і зрівняється з ним. Ви також можете зробити це без $tmpфайлу:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
Другий head"хитрощі" cat, поставивши середнього чоловіка між ним та операцією запису. Ви можете також обдурити catіншого cat, але це непослідовно. Спробуйте це:
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
Змушує sedчитати весь файл як рядок, захоплює його, а потім вставляє його $total_repeatsкілька разів.
Це, звичайно, не вдасться, якщо у вашому файлі є будь-які нульові символи. Виберіть того, якого ви знаєте, там немає.
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
}
Це все зараз хлопці, я сподіваюся, що ця довільна відповідь нікого не турбувала. Я перевіряв їх усіх багато разів, але я лише дворічний користувач оболонки, тому майте на увазі, я думаю. Тепер спати ...
rm $tmp