2012-03-12 40 views
14

Tôi đang cố gắng thay thế văn bản trong một tệp nhiều dòng bằng cách sử dụng dòng lệnh perl. Tôi đang sử dụng Ubuntu Natty.Dòng lệnh Perl nhiều dòng thay thế

Dưới đây là nội dung của tập tin văn bản của tôi (gọi tắt là test.txt):

[mysqld] 
# 
# * Basic Settings 
# 

# 
# * IMPORTANT 
# If you make changes to these settings and your system uses apparmor, you may 
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld. 
# 

user   = mysql 
socket   = /var/run/mysqld/mysqld.sock 
port   = 3306 
basedir   = /usr 
datadir   = /var/lib/mysql 
tmpdir   = /tmp 
skip-external-locking 

Dưới đây là lệnh perl của tôi:

perl -i -pe "s/(\[mysqld\][^\^]+)/\1\nsometext/g" test.txt 

Tuy nhiên, thay vì thay thế tất cả các văn bản trong tập tin , dưới đây là những gì tôi kết thúc với:

[mysqld] 

sometext# 
# * Basic Settings 
# 

# 
# * IMPORTANT 
# If you make changes to these settings and your system uses apparmor, you may 
# also need to also adjust /etc/apparmor.d/usr.sbin.mysqld. 
# 

user   = mysql 
socket   = /var/run/mysqld/mysqld.sock 
port   = 3306 
basedir   = /usr 
datadir   = /var/lib/mysql 
tmpdir   = /tmp 
skip-external-locking 
# 

Tôi đã thử Regex trong RegexBuddy cho Perl và khớp với es tất cả mọi thứ trong tập tin văn bản, nhưng đối với một số lý do nó không hoạt động bằng cách sử dụng perl trên dòng lệnh.

Tôi đánh giá cao một số trợ giúp.

Xin cảm ơn trước.

+5

Tôi không chắc chắn kết quả mong đợi sẽ là gì. – cornuz

+0

@cornuz Tôi nghĩ đó là điều hiển nhiên từ câu hỏi. Tôi nói "thay vì thay thế tất cả các văn bản trong tập tin, [sau đây] là những gì tôi kết thúc với ..." do đó, khá nhiều giải thích nó. Cũng từ biểu thức chính quy, tôi nghĩ nó có vẻ khá rõ ràng về kết quả mà tôi yêu cầu. –

Trả lời

24

Bạn đang đọc tệp theo từng dòng, vì vậy chỉ dòng đầu tiên khớp với regex của bạn. Điều bạn sẽ muốn làm - nếu bạn thực sự muốn xóa hầu hết nội dung - hãy vuốt tệp bằng cách sử dụng tùy chọn -0, ví dụ: -0777. Đây là quá trình xử lý kết thúc dòng và 777 chỉ là một số được sử dụng theo quy ước dưới dạng số bát phân đủ lớn để làm cho tệp bị trượt.

perl -0777 -i -pe 's/(\[mysqld\][^\^]+)/$1\nsometext/g' test.txt 

Ngoài ra, tôi đã thay thế dấu ngoặc kép của bạn. Nếu bạn đang ở trong * nix, có vẻ như bạn đang có, dấu nháy đơn là thích hợp hơn. Trường hợp tại điểm, $1 sẽ không được nội suy bởi lớp vỏ.

+0

Cảm ơn bạn rất nhiều. Tôi đã phải sửa đổi nó thành: 'perl -0777 -i -pe' s/(\ [mysqld \] [^ \ ^] +)/\ 1 \ nsometext/g "test.txt' vì tôi sẽ cần phải sử dụng một số biến shell sau này. Chúc mừng. –

+0

@ChuckUgwuh Rất vui được giúp đỡ. – TLP

+0

Chúc mừng. Bạn có biết làm thế nào tôi có thể bao gồm các biến shell sử dụng dấu nháy đơn? Trong ngoặc kép tôi làm một cái gì đó như thế này: 'perl -0777 -i -pe" s/(\ [mysqld \] [^ \ ^] +)/\ 1 \ n $ var/g "test.txt', nó sẽ được tốt đẹp để biết làm thế nào tôi có thể đạt được điều tương tự bằng cách sử dụng dấu nháy đơn? Cảm ơn một lần nữa. –

5

-p switch làm cho Perl lặp lại trên mỗi dòng dòng của đầu vào và thực thi mã đã cho cho mỗi đầu vào (và để in dòng sau). Cụ thể, lệnh

perl -p -e 'SOME_CODE_HERE;' 

là chính xác tương đương với chạy chương trình Perl sau:

LINE: while (<>) { 
    SOME_CODE_HERE; 
} continue { 
    print or die "-p destination: $!\n"; 
} 

regexp của bạn dường như được thiết kế để phù hợp với nhiều dòng cùng một lúc, mà rõ ràng là sẽ không hoạt động nếu Perl là xử lý dòng đầu vào theo dòng. Để làm cho nó làm việc như mong đợi, bạn có (ít nhất) hai lựa chọn: khái niệm về những gì tạo nên một dòng bằng -0NNN switch

  1. Thay đổi Perl. Cụ thể, công tắc -0777 khiến Perl xử lý mọi tệp đầu vào dưới dạng một "dòng" duy nhất.

  2. Viết lại mã của bạn, ví dụ: sử dụng .. flip-flop operator.

Nhân tiện, tôi nghi ngờ rằng regexp của bạn không có nghĩa là ý nghĩa của bạn. Cụ thể, [^\^]+ khớp với một chuỗi gồm một hoặc nhiều ký tự không chứa dấu mũ (^). Vì đầu vào của bạn dường như không chứa bất kỳ dấu mũ nào, điều này dường như về cơ bản tương đương với (?s:.+) (hoặc chỉ .+ nếu bạn sử dụng /s modifier).

+0

Cảm ơn. Tôi không hoàn toàn hiểu biết về dòng lệnh như câu trả lời của bạn, nhưng tôi thấy nó khá giáo dục. Chúc mừng –

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