Vấn đề là ở đó tiếng kêu
sẽ chạy trên từng dòng chứ không phải toàn bộ tệp. Miễn là tệp đủ nhỏ để vừa với bộ nhớ (điều này sẽ xảy ra trong phần lớn các tình huống ngày nay), bạn có thể sử dụng grep's -z
cờ để nhét toàn bộ tệp:
-z, --null-dữ liệu
Xử lý dữ liệu đầu vào và đầu ra dưới dạng chuỗi các
dòng, mỗi dòng kết thúc bằng một byte không (mã ASCII NUL
ký tự) thay vì một dòng mới. Giống như tùy chọn -Z hoặc --null, tùy chọn này có thể được sử dụng với các lệnh
như sort -z để xử lý các tên tệp tùy ý.
Vấn đề tiếp theo, là nếu bạn vượt qua tiếng kêu
một cái gì đó có dòng mới, nó sẽ coi nó như một danh sách các mẫu để grep:
$chuỗi="1
> 2"
$ tiếp theo 10 | grep "$string"
1
2
10
"
Điều đó có nghĩa là tôi e rằng bạn sẽ phải diễn đạt mẫu dưới dạng một biểu thức chính quy thích hợp:
\n\ntest1\n\ntest2\n\n
Tuy nhiên, điều này cũng có nghĩa là bạn cần -P
để kích hoạt các biểu thức chính quy tương thích với perl để \N
sẽ làm việc.
Tôi đã tạo hai tệp này để chứng minh:
$ mèo tệp1
đây là một bài kiểm tra:
kiểm tra1
kiểm tra2
và một cái khác
$ mèo tệp2
đây là một bài kiểm tra:
kiểm tra1
kiểm tra2
và một cái khác
Sử dụng hai tệp đó và thông tin ở trên, bạn có thể thực hiện:
$ grep -Pz '\n\ntest1\n\ntest2\n\n' file1
$
$ grep -Pz '\n\ntest1\n\ntest2\n\n' file2
đây là một bài kiểm tra:
kiểm tra1
kiểm tra2
và một cái khác
Đặt tất cả những điều này lại với nhau mang lại cho chúng ta:
chuỗi='\n\ntest1\n\ntest2\n\n'
nếu ! grep -Pzq "$string" test.txt; sau đó
printf "$string" >> test.txt
fi
Hoặc, như được đề xuất bởi @steeldriver trong một nhận xét, bạn có thể sử dụng một biến và chuyển đổi các dòng mới thành \N
một cách nhanh chóng:
$chuỗi="
kiểm tra1
kiểm tra2
"
$ nếu ! grep -Pzq "${string//$'\n'/\n}" test.txt; sau đó
printf "$string" >> test.txt
fi
Nếu chuỗi của bạn chứa các ký tự đặc biệt có ý nghĩa trong các biểu thức thông thường, như bạn hiện đang hiển thị trong câu hỏi được cập nhật của mình, thì đó là một tình huống hoàn toàn khác. Đối với ví dụ bạn hiển thị, bạn sẽ cần thứ gì đó phức tạp hơn nhiều. Như thế này:
searchString='\n\nif \[ -f ~/.script \]; sau đó\s*\n\s*\.\s+~/\.script\s*\nfi\n\n'
printString='
nếu [ -f ~/.script ]; sau đó
. ~/.script
fi
'
nếu ! grep -Pzq "$searchString" test.txt; sau đó
printf "%s" "$printString" >> test.txt
fi