Làm thế nào tôi có thể tìm thấy và thay thế cụ thể từ trong một tập tin văn bản bằng dòng lệnh?
sed -i 's/original/new/g' file.txt
Lời giải thích:
-
sed
= Dòng EDitor -
-i
= ở chỗ (tức là lưu lại các tập tin gốc) -
Lệnh chuỗi:
-
s
= thay thế lệnh -
original
= một biểu hiện thường xuyên mô tả những từ để thay thế (hoặc chỉ là những lời tự) -
new
= các văn bản để thay thế nó với -
g
= global (tức là thay thế tất cả và không phải chỉ là người đầu tiên xuất hiện)
-
file.txt
= tên tập tin
Có nhiều cách để đạt được nó. Tùy thuộc vào sự phức tạp của những ai cố gắng để đạt được với chuỗi thay thế, và tùy thuộc vào công cụ mà dùng được quen, một vài phương pháp có thể được ưu tiên hơn những người khác.
Trong câu trả lời này tôi đang sử dụng đơn giản input.txt
tập tin, mà bạn có thể sử dụng để kiểm tra tất cả các ví dụ cung cấp ở đây. Các tập tin nội dung:
roses are red , violets are blueThis is an input.txt and this doesn't rhyme
BASH
Bash không thực sự có ý nghĩa đối xử lý văn bản, nhưng đơn giản thay thế có thể được thực hiện thông qua tham số mở rộng đặc biệt ở đây, chúng ta có thể sử dụng cấu trúc đơn giản ${parameter/old_string/new_string}
.
#!/bin/bashwhile IFS= read -r linedo case "$line" in *blue*) printf "%s\n" "${line/blue/azure}" ;; *) printf "%s\n" "$line" ;; esacdone < input.txt
Này kịch bản nhỏ đó không làm ở chỗ thay thế có nghĩa là bạn sẽ phải cứu văn bản mới đến tập tin mới, và xóa các tập tin cũ, hoặc mv new.txt old.txt
Bên lưu ý: nếu bạn đang tò mò về lý do tại sao while IFS= read -r ; do ... done < input.txt
được sử dụng nó vỏ là cách đọc thấy từng dòng. Xem này để tham khảo.
Chiếc ô
Chiếc ô, là một văn bản xử lý tiện ích, khá là thích hợp cho nhiệm vụ như vậy. Nó có thể làm đơn giản và thay thế tiên tiến hơn nhiều người dựa vào thường. Nó cung cấp hai chức năng: sub()
và gsub()
. Đầu tiên chỉ thay thế chỉ là người đầu tiên xuất hiện, trong khi những thứ hai - thay thế những sự kiện trong toàn bộ chuỗi. Ví dụ, nếu chúng ta có chuỗi one potato two potato
đây sẽ là kết quả:
$ echo "one potato two potato" | awk '{gsub(/potato/,"banana")}1'one banana two banana$ echo "one potato two potato" | awk '{sub(/potato/,"banana")}1' one banana two potato
Chiếc ô có thể có một đầu vào tập tin như lập luận, vì thế làm điều tương tự với input.txt
sẽ dễ dàng:
awk '{sub(/blue/,"azure")}1' input.txt
Tùy thuộc vào phiên bản của chiếc ô bạn có, nó có thể có hoặc không có ở nơi chỉnh sửa, vì thế bình thường, thực tế là tiết kiệm và thay thế văn bản mới. Ví dụ như một cái gì đó như thế này:
awk '{sub(/blue/,"azure")}1' input.txt > temp.txt && mv temp.txt input.txt
SED
Sed là một đường biên tập. Nó cũng sử dụng biểu thức thông thường, nhưng cho đơn giản thay thế nó là đủ để làm:
sed 's/blue/azure/' input.txt
Những điều tốt về công cụ này là nó có ở chỗ sửa đổi, mà bạn có thể cho phép với -i
cờ.
Perl
Perl là một công cụ mà thường được dùng để xử lý văn bản, nhưng đó là một ngôn ngữ chung mục đích, và được sử dụng trong mạng, quản lý hệ thống máy tính để bàn dụng, và nhiều chỗ khác. Nó vay rất nhiều khái niệm/năng từ ngôn ngữ khác, như C,sed,chiếc ô, và những người khác. Đơn giản thay thế có thể được thực hiện như vậy:
perl -pe 's/blue/azure/' input.txt
Như sed, perl cũng có -tôi cờ.
Python
Ngôn ngữ này là rất linh hoạt và cũng được sử dụng trong một loạt các ứng dụng. Nó có rất nhiều chức năng để làm việc với dây, trong đó được replace()
vì vậy, nếu bạn có thay đổi như thế var="Hello World"
bạn , bạn có thể làm var.replace("Hello","Good Morning")
Cách đơn giản để xem tập tin trong và ngoài đó, nó sẽ được như vậy:
python -c "import sys;lines=sys.stdin.read();print lines.replace('blue','azure')" < input.txt
Với Python, tuy nhiên, bạn cũng cần phải ra để tập tin mới , mà bạn có thể cũng làm từ bên trong kịch bản thân. Ví dụ, đây là một trong những đơn giản:
#!/usr/bin/env pythonimport sysimport osimport tempfiletmp=tempfile.mkstemp()with open(sys.argv[1]) as fd1, open(tmp[1],'w') as fd2: for line in fd1: line = line.replace('blue','azure') fd2.write(line)os.rename(tmp[1],sys.argv[1])
Kịch bản này được gọi là với input.txt
như dòng lệnh lập luận. Chính xác lệnh để chạy python kịch bản với dòng lệnh tranh luận sẽ được
$ ./myscript.py input.txt
hay
$ python ./myscript.py input.txt
Tất nhiên, hãy chắc chắn rằng ./myscript.py
là trong thư mục hiện tại và cho cách đầu tiên, đảm bảo nó là thiết thực thi với chmod +x ./myscript.py
Python cũng có thể có thường xuyên biểu hiện đặc biệt , có re
module, mà có re.sub()
chức năng đó có thể được sử dụng để nâng cao hơn thay thế.
Có một số cách khác nhau để làm điều này. Một sử dụng sed
và Dom. SED là một Dòng Biên tập viên cho bộ lọc và chuyển văn bản. Một ví dụ như sau:
marco@imacs-suck: ~$ echo "The slow brown unicorn jumped over the hyper sleeping dog" > orlymarco@imacs-suck: ~$ sed s/slow/quick/ < orly > yarlymarco@imacs-suck: ~$ cat yarlyThe quick brown unicorn jumped over the hyper sleeping dog
Một cách khác mà có thể làm ý nghĩa hơn < strin
và > strout
là với đường ống!
marco@imacs-suck: ~$ cat yarly | sed s/unicorn/fox/ | sed s/hyper/lazy/ > nowaimarco@imacs-suck: ~$ cat nowai The quick brown fox jumped over the lazy sleeping dog
Qua chiếc ô của gsub lệnh,
awk '{gsub(/pattern/,"replacement")}' file
Ví dụ:
awk '{gsub(/1/,"0");}' file
Trong ví dụ trên tất cả các 1 's được thay thế bằng 0' s không phân biệt của các cột nơi nó nằm.
Nếu bạn muốn làm một sự thay thế vào một cột cụ thể sau đó, làm như thế này,
awk '{gsub(/pattern/,"replacement",column_number)}' file
Ví dụ:
awk '{gsub(/1/,"0",$1);}' file
Nó sẽ thay thế với 1 0 trên cột đầu tiên chỉ.
Qua Perl,
$ echo 'foo' | perl -pe 's/foo/bar/g'bar
Bạn có thể sử dụng Tên trong chế độ Cũ:
ex -s -c '%s/OLD/NEW/g|x' file
%
chọn tất cả các dòngs
thay thếg
thay thế tất cả các trường ở mỗi dòngx
viết nếu đã có những thay đổi (họ có) và lối ra
sed
là những stream edhiệu lực bằng gỗ ở đó, bạn có thể sử dụng |
(ống) để gửi chuẩn suối (Thiết bị nhập và thiết bị xuất chuẩn đặc biệt) qua sed
và thay đổi họ lập trình trên bay, làm cho nó một công cụ trong triết lý Unix truyền thống, nhưng có thể sửa các tập tin trực tiếp luôn, sử dụng những -i
tham số đề cập dưới đây.
Xem xét phía sau:
sed -i -e 's/few/asd/g' hello.txt
s/
được sử dụng để substitute tìm thấy biểu hiện few
với asd
:
Một vài người, những người dũng cảm.
Các kỷ, những người dũng cảm.
/g
là viết tắt cho "toàn cầu", có nghĩa là để làm điều này cho toàn bộ dòng. Nếu bạn rời khỏi /g
(với s/few/asd/
có , luôn luôn cần phải được ba, bây giờ không có vấn đề gì) và few
xuất hiện hai lần trên cùng một dòng, chỉ là lần đầu tiên few
được thay đổi asd
:
Vài người đàn ông, một vài phụ nữ, người dũng cảm.
Các kỷ người đàn ông, một vài phụ nữ, người dũng cảm.
Điều này rất hữu ích trong một số hoàn cảnh như thế thay đổi nhân vật đặc biệt vào sự khởi đầu của đường (ví dụ thay thế nhiều hơn là biểu tượng một số người sử dụng để báo trước liệu chủ đề email với một ngang tab, trong khi lại một trích đại sự bất bình đẳng sau ở đường dây bị ảnh hưởng), nhưng trong ví dụ bạn xác định rằng bất cứ nơi nào few
xảy ra, nó sẽ được thay thế hãy chắc chắn rằng bạn có mà /g
.
Sau hai lựa chọn (cờ) được kết hợp thành một, -ie
:
-i
lựa chọn được sử dụng để sửa in nơi trên các tập tin hello.txt
.
-e
cho thấy sự lựa chọn emarley/lệnh để chạy, trong trường hợp này s/
.
Chú ý: Nó quan trọng là bạn sử dụng -i -e
để tìm kiếm/thay thế. Nếu bạn làm -ie
bạn tạo ra một bản sao lưu của tất cả các tập tin với chữ 'e' nối.
Bạn có thể làm như thế này:
locate <part of filaname to locate> | xargs sed -i -e "s/<Old text>/<new text>/g"
Ví dụ:để thay thế tất cả các sự kiện [logdir', "] (mà [] ) với [logdir' hệ điều hành.getcwd()] trong tất cả các tập tin được kết quả của xác định vị trí chỉ huy, làm:
ex1:
locate tensorboard/program.py | xargs sed -i -e "s/old_text/NewText/g"
ex2:
locate tensorboard/program.py | xargs sed -i -e "s/logdir', ''/logdir', os.getcwd()/g"
nơi [tensorboard/program.py] được tập tin để tìm kiếm