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 head
mộ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ử N
là 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 file
gọi file2
, total_repeats
là số lần file
sẽ cần phải được thêm vào file2
để làm cho nó giống như khi file
được nối với N
thờ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^Loops
nê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.
tee
với MATH
<file tee -a file | head -n $total_lines > $tmp
cat $tmp > file
Đây tee
là đọc từ file
như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 head
dừ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ừ file
quá.
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 $tmp
tập tin:
eval "cat $(yes file | head -n $total_repeats | tr '\n' ' ')" |
head -n $((total_lines-linecount)) >> file
head
"Thủ thuật" thứ hai cat
bằ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 cat
người khác cat
như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_repeats
số 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