Мені нудно, ось ось ще кілька методів, як об'єднати файл у себе, в основному, 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