2012-01-21 38 views
12

Tôi có một tài liệu văn bản đơn giản, mà tôi muốn biên dịch bên trong LaTeX. Tuy nhiên, đôi khi nó có các ký tự, "#", "$", "%", "&" và "_". Để biên dịch đúng trong LaTeX, trước tiên tôi phải thay thế các ký tự này bằng "#", "\ $", "\%", "\ &" và "_". Tôi đã sử dụng dòng này trong sed:

sed -i 's/\#/\\\#/g' ./file.txt 
sed -i 's/\$/\\\$/g' ./file.txt 
sed -i 's/\%/\\\%/g' ./file.txt 
sed -i 's/\&/\\\&/g' ./file.txt 
sed -i 's/\_/\\\_/g' ./file.txt 

Điều này có đúng không?

Thật không may, tệp quá lớn để mở trong bất kỳ phần mềm GUI nào, vì vậy hãy kiểm tra xem dòng sed của tôi có chính xác không bằng trình soạn thảo văn bản. Tôi đã cố gắng tìm kiếm với grep, nhưng việc tìm kiếm không hoạt động như mong đợi (ví dụ dưới đây, tôi đã tìm kiếm cho bất kỳ dòng có chứa "$"):

grep "\$" file.txt 
  • là gì cách tốt nhất để đưa "\" trước của những nhân vật này?
  • Tôi làm cách nào để sử dụng grep để kiểm tra thành công các dòng có thay thế?
+1

Bạn có thể đảm bảo rằng bạn không có bất kỳ ký tự đặc biệt nào được ALREADY thoát? – wim

+1

Grep hoạt động như thế nào, nếu không như mong đợi? – chepner

+0

Khi tôi chạy 'grep '\ $" file.txt' có vẻ như đang in mọi thứ ra hoặc gần như mọi thứ. Tôi không biết tại sao nó in quá nhiều văn bản, vì "$" là khá hiếm. – Village

Trả lời

21

bạn có thể. làm việc thay thế với một cuộc gọi duy nhất để sed:.

sed -i -E 's/([#$%&_\])/\\&/g' file.txt 

các & trong văn bản thay thế lấp đầy cho bất cứ nhân vật duy nhất được đặt trong dấu ngoặc Lưu ý rằng kể từ khi \ là nhân vật LaTeX thoát, bạn sẽ phải thoát nó cũng như trong tập tin gốc.

+1

Được thực hiện tốt đẹp! +1 –

+3

Dấu ngoặc đơn không cần thiết. Một số phiên bản 'sed' không hỗ trợ' -E', nhưng thay vào đó hãy sử dụng '-r'. Một số phiên bản của 'sed' yêu cầu phần mở rộng sau' -i', nhưng vì OP không cung cấp một phiên bản trong câu hỏi nên an toàn cho rằng nó không cần thiết. –

+2

Điểm tốt, tất cả. Tôi sẽ đề cập rằng -E sẽ phụ thuộc vào phiên bản là sed sử dụng, nhưng phải xóa nó từ phiên bản cuối cùng. – chepner

2

Tôi nghĩ rằng vấn đề của bạn là bản thân bash đang xử lý những lần thoát đó.

  1. Những gì bạn có với tôi. Nhưng cảnh báo: nó cũng sẽ thoát gấp đôi, ví dụ: một số \# đã được thoát. Nếu đó không phải là những gì bạn muốn, bạn có thể muốn sửa đổi các mẫu của mình để kiểm tra xem có chưa có \ trước đó hay không.
  2. $ được sử dụng cho cú pháp thay thế lệnh bash. Tôi đoán grep "\\$" file.txt nên làm những gì bạn mong đợi.
4
sed -i 's/\#/\\\#/g' ./file.txt 
sed -i 's/\$/\\\$/g' ./file.txt 
sed -i 's/\%/\\\%/g' ./file.txt 
sed -i 's/\&/\\\&/g' ./file.txt 
sed -i 's/\_/\\\_/g' ./file.txt 

Bạn không cần \ trên (tìm kiếm) đầu tiên chuỗi trên hầu hết trong số họ, chỉ $ (đó là một nhân vật đặc biệt, có nghĩa là kết thúc của một dòng; còn lại là không đặc biệt) . Và trong thay thế, bạn chỉ cần hai \\, không phải ba. Ngoài ra, bạn có thể làm điều đó tất cả trong một với một số -e báo cáo:

sed -i.bak -e 's/#/\\#/g' \ 
      -e 's/\$/\\$/g' \ 
      -e 's/%/\\%/g' \ 
      -e 's/&/\\&/g' \ 
      -e 's/_/\\_/g' file.txt 

Bạn không cần phải tăng gấp đôi-thoát khỏi bất cứ điều gì (trừ \\) vì đây là những đơn trích dẫn. Trong số grep, bash của bạn là diễn giải lối thoát trên $ vì đó là ký tự đặc biệt (cụ thể là sigil cho biến), do đó, grep đang tìm và chỉ tìm kiếm $, ký tự đặc biệt có nghĩa là kết thúc của một dòng. Bạn cần một trong hai đơn quote nó để ngăn chặn bash từ giải thích \ ('\$', hoặc thêm một cặp \\: "\\\$". Presumably, that's where you're getting the \ `từ, nhưng bạn không cần nó trong sed vì nó được viết

+0

Vì "$" là đặc biệt, có cần ba '\' (ví dụ: '\\\') ở phía trước không? – Village

+1

@Village Không thay thế. – Kevin

2

tôi không đáp ứng cho sed, các câu trả lời khác là enougth tốt ;-)

Bạn có thể sử dụng less như người xem để kiểm tra tập tin khổng lồ của bạn (hoặc more, nhưng less là thoải mái hơn more).

Để tìm kiếm, bạn có thể sử dụng fgrep: bỏ qua cụm từ thông dụng =>fgrep '\$' thực sự sẽ tìm kiếm văn bản \$. fgrep giống như gọi grep -F.

EDIT: fgrep '\$'fgrep "\$" là khác nhau. Trong trường hợp thứ hai, bash diễn giải chuỗi và sẽ thay thế bằng một ký tự đơn: $ (ví dụ: fgrep sẽ chỉ tìm kiếm $).

Các vấn đề liên quan