Мне скучно, так что вот еще несколько способов, как объединить файл с самим собой, в основном с 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
раз.
Сказал, что МАТ здесь, более или менее: МАТ (сущность)
Это первый семестр по информатике, но прошло много времени с тех пор, как я сделал доказательство индукции, поэтому я не могу с этим справиться ... (также хорошо известен этот класс рекурсии, 2^Loops
так что это тоже есть ...)
POSIX
Я использую несколько не-posix вещей, но они не являются необходимыми. Для моих целей:
yes() { while true; do echo "$1"; done; }
О, я только использовал это. Ну что ж, раздел уже здесь ...
методы
head
с отслеживанием linecount.
ln=$linecount for i in $(seq 1 $N); do <file head -n $ln >> file; ln=$((ln*2)) done
Нет временных файлов, нет кота, даже не слишком много математики, все радость.
tee
с математикой
<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="$" 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