Làm cách nào để xóa tất cả các dòng khỏi tệp văn bản có chứa các từ "cat" và "rat"?
Làm cách nào để xóa tất cả các dòng khỏi tệp văn bản có chứa các từ "cat" và "rat"?
Câu trả lời:
grep
tiếp cậnĐể tạo một bản sao của tệp không có dòng khớp với "cat" hoặc "rat", người ta có thể sử dụng grep
ngược lại ( -v
) và với tùy chọn toàn từ ( -w
).
grep -vwE "(cat|rat)" sourcefile > destinationfile
Tùy chọn toàn từ đảm bảo rằng nó sẽ không khớp cats
hoặc grateful
ví dụ. Chuyển hướng đầu ra của shell của bạn được sử dụng ( >
) để ghi nó vào một tệp mới. Chúng ta cần -E
tùy chọn để kích hoạt các biểu thức chính quy mở rộng cho (one|other)
cú pháp.
sed
tiếp cậnNgoài ra, để loại bỏ các dòng tại chỗ, người ta có thể sử dụng sed -i
:
sed -i "/\b\(cat\|rat\)\b/d" filename
Các \b
ranh giới bộ văn bản và các d
hoạt động xóa các dòng phù hợp với khái niệm giữa các dấu gạch chéo. cat
và rat
cả hai đều được khớp với (one|other)
cú pháp mà chúng ta rõ ràng cần phải thoát bằng dấu gạch chéo ngược.
Mẹo: sử dụng sed
mà không có -i
toán tử để kiểm tra đầu ra của lệnh trước khi ghi đè tệp.
(Dựa trên Sed - Xóa một dòng có chứa một chuỗi cụ thể )
Để chỉ kiểm tra trong thiết bị đầu cuối, sử dụng:
sed '/[cr]at/d' file_name
Để thực sự xóa những dòng đó khỏi tệp, sử dụng:
sed -i '/[cr]at/d' file_name
Xem xét nếu bạn có tập tin với file_name
và bạn muốn tìm kiếm cho chuột nhưng trên cùng một lúc vài dòng từ chuột có Nói cách khác như cat
và rat
và bạn không muốn nhìn thấy những người ở đầu ra của bạn, vì vậy một trong những cách để làm điều đó là -
grep -r mouse file_name | grep -vE "(cat|rat)"
Làm việc tại /bin/sh
, đó là dash
trên Ubuntu, cũng như ksh
, và bash
. Hơi khó xử khi bạn phải viết nhiều trường hợp kiểm tra cho mỗi từ trong case
câu lệnh nhưng di động. Hoạt động với các trường hợp từ xuất hiện một mình trên dòng, ở đầu, cuối dòng hoặc giữa dòng và bỏ qua nơi nó có thể là một phần của từ khác.
#!/bin/sh
line_handler(){
# $1 is line read, prints to stdout
case "$1" in
cat|cat\ *|*\ cat\ *|*\ cat) true;; # do nothing if cat or rat in line
rat|rat\ *|*\ rat\ *|*\ rat) true;;
*) printf "%s\n" "$1"
esac
}
readlines(){
# $1 is input file, the rest is words we want to remove
inputfile="$1"
shift
while IFS= read -r line;
do
line_handler "$line" "$@"
done < "$inputfile"
[ -n "$line" ] && line_handler "$line"
}
readlines "$@"
Và đây là cách nó hoạt động:
$ cat input.txt
the big big fat cat
the cat who likes milk
jumped over gray rat
concat
this is catchy
rat
rational
irrational
$ ./dellines.sh input.txt
concat
this is catchy
rational
irrational