Tôi thấy chán vì vậy đây là một vài phương pháp nữa về cách ghép một tệp với chính nó, chủ yếu là với headmột cái nạng. Xin lỗi nếu tôi thể hiện quá mức bản thân, tôi chỉ thích nói những điều: P
Giả sử Nlà số lượng tự ghép bạn muốn làm và tệp của bạn được đặt tên file.
Biến:
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)
Cho một bản sao của cuộc filegọi file2, total_repeatslà số lần filesẽ cần phải được thêm vào file2để làm cho nó giống như khi fileđược nối với Nthời gian của chính nó .
MATH đã nói ở đây, ít nhiều: MATH (ý chính)
Đó là công cụ khoa học máy tính học kỳ đầu tiên nhưng đã được một thời gian kể từ khi tôi làm bằng chứng cảm ứng nên tôi không thể vượt qua nó ... (cũng là lớp đệ quy này khá nổi tiếng 2^Loopsnên cũng vậy ....)
POSIX
Tôi sử dụng một vài thứ không phải là posix nhưng chúng không cần thiết. Đối với mục đích của tôi:
yes() { while true; do echo "$1"; done; }
Ồ, tôi chỉ sử dụng nó. Ồ, phần này đã ở đây ...
Phương pháp
head với theo dõi linecount.
ln=$linecount
for i in $(seq 1 $N); do
<file head -n $ln >> file;
ln=$((ln*2))
done
Không có tập tin tạm thời, không có con mèo, thậm chí không có quá nhiều toán học, tất cả niềm vui.
teevới MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Đây teelà đọc từ filenhưng liên tục nối vào nó, vì vậy nó sẽ tiếp tục đọc tệp lặp lại cho đến khi headdừng nó. Và chúng tôi biết khi nào nên dừng nó vì MATH . Việc nối thêm quá mức, vì vậy tôi đã sử dụng tệp tạm thời. Bạn có thể cắt các dòng thừa từ filequá.
eval, chúa tể bóng tối!
eval "cat $(yes file | head -n $((total_repeats+1)) | tr '\n' ' ')" > $tmp
cat $tmp > file
Điều này chỉ mở rộng cat file file file ...và đánh bại nó. Bạn cũng có thể làm điều đó mà không cần $tmptập tin:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
head"Thủ thuật" thứ hai catbằng cách đặt một người trung gian giữa nó và thao tác ghi. Bạn cũng có thể lừa catngười khác catnhưng điều đó có hành vi không nhất quán. Thử đi:
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
Buộc sedđọc toàn bộ tập tin dưới dạng một dòng, ghi lại tất cả, sau đó dán $total_repeatssố lần.
Tất nhiên điều này sẽ thất bại nếu bạn có bất kỳ ký tự null nào trong tệp của mình. Chọn một cái mà bạn biết là không có ở đó.
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
}
Đó là tất cả cho đến bây giờ, tôi hy vọng câu trả lời độc đoán này đã không làm phiền bất cứ ai. Tôi đã thử nghiệm tất cả chúng nhiều lần nhưng tôi chỉ là người dùng shell hai năm nên tôi nhớ điều đó. Bây giờ đi ngủ ...
rm $tmp