2010-02-16 32 views
7

Tôi đang ở thư mục với các file bao gồm nhiều dòng dòng như thế này:sed lỗi - unterminated thay thế mẫu

98.684807 :(float) 
52.244898 :(float) 
46.439909 :(float) 

và sau đó một dòng chấm dứt:

[chuck]: cleaning up... 

Tôi cố gắng để loại bỏ :(float) từ mọi tệp (nhưng để lại số) và cũng xóa dòng đó làm sạch ... dòng.

tôi có thể nhận được:

sed -ie 's/ :(float)//g' * 

để làm việc, nhưng điều đó sẽ tạo ra các file mà giữ các tập tin cũ. Việc xóa cờ -e sẽ dẫn đến lỗi mẫu thay thế không được chuẩn bị.

Tương tự đối phó với:

sed -ie 's/[chuck]: cleaning up...//g' * 

Suy nghĩ?

+0

"Tạo tệp giữ các tệp cũ" có nghĩa là gì? –

+0

Nếu tôi có một tệp có tên là abc. Nó loại bỏ các dòng từ tập tin abc, nhưng tạo ra một tập tin gọi là abce. –

+2

'g' không cần thiết nếu mẫu chỉ xuất hiện một lần trên mỗi dòng. –

Trả lời

1
sed -i -e 's/ :(float)//g' * 
11
sed -i '' -e 's/:(float)//' -e '/^.chuck/d' * 

Bằng cách này bạn đang nói với sed không lưu một (gia hạn backup rỗng dài để -i) sao chép và xác định riêng rẽ các lệnh sed.

3
sed -ie expression [files...] 

tương đương với:

sed -ie -e expression [files...] 

và cả hai có nghĩa là áp dụng biểu thức để tác phẩm, ghi đè lên các tập tin, nhưng lưu các tập tin cũ với một "e" là hậu tố sao lưu.

Tôi nghĩ rằng bạn muốn: sed -i biểu -e [file ...]

Bây giờ nếu bạn đang nhận được một lỗi từ rằng phải có một cái gì đó sai với expression của bạn.

3

các số của bạn được tách riêng với (float) bởi ký tự :. Do đó, bạn có thể sử dụng awk/cut để lấy số của bạn. Đơn giản hơn một regex

$ head -n -1 file | awk -F":" '{print $1}' 
98.684807 
52.244898 
46.439909 

$ head -n -1 file | cut -d":" -f1 
98.684807 
52.244898 
46.439909 
1

Kiểm tra xem bạn có tên tệp lạ nào trong thư mục không.

Dưới đây là một cách để lặp lại lỗi lầm của mình:

$ touch -- "-e s:x:" 
$ ls 
-e s:x: 
$ sed -i "s/ :(float)//g' * 
sed: -e expression #1, char 5: unterminated `s' command 

Một cách để bảo vệ chống lại điều này là sử dụng một dấu gạch ngang đôi chấm dứt các tùy chọn để sed khi bạn sử dụng một thẻ hoang dã:

$ sed -i "s/ :(float)//g' -- * 

Bạn có thể làm điều tương tự để xóa tệp:

$ rm "-e s:x:" 
rm: invalid option -- 'e' 
$ rm -- "-e s:x:" 
1

Giải pháp:

sed -i '' 's/ :(float)//g' *

sed -i '' 's/[chuck]: cleaning up...//g' *

Giải thích:

tôi có thể nhận được:

sed -ie 's/ :(float)//g' * 

để hoạt động, nhưng điều đó tạo ra các tệp giữ các tệp cũ.

Đó là bởi vì sed 's i cờ là nghĩa vụ phải làm việc theo cách

-i extension

Edit files in-place, saving backups with the specified extension. If a zero-length extension is given, no backup will be saved.

rằng Trong trường hợp này e đang được hiểu là biện pháp mở rộng bạn muốn lưu bản sao lưu của bạn với. Vì vậy, tất cả các tệp gốc của bạn sẽ được sao lưu với một số e được thêm vào tên của chúng.

Để cung cấp tiện ích mở rộng bằng không, bạn cần sử dụng -i ''.

Lưu ý: Không giống như -i<your extension>, -i'' sẽ không hoạt động. Bạn cần có một ký tự khoảng trắng giữa -i'' để nó hoạt động.


Xóa cờ -e dẫn đến lỗi mẫu thay thế chưa được hoàn thành.

Khi bạn loại bỏ các -ie ngay sau, ví dụ:

sed -i 's/ :(float)//g' *

s/ :(float)//g bây giờ sẽ được giải thích như là mở rộng lập luận để i cờ.Và file đầu tiên trong danh sách các tập tin được tạo ra bởi sự bành trướng vỏ * được hiểu như là một sed function (có lẽ hầu hết s/regular expression/replacement/flags chức năng) Bạn có thể xác minh điều này bằng cách kiểm tra đầu ra của

sedfn=$(echo * | cut -d' ' -f1); [[ ${sedfn:0:1} == "s" ]]; echo $?

Nếu đầu ra của trên chuỗi lệnh là 0, giả định của chúng tôi được xác thực. Cũng trong trường hợp này, nếu bằng cách nào đó tên tập tin đầu tiên đủ điều kiện như một hàm sed hợp lệ s/regular expression/replacement/flags, các tên tệp khác sẽ được hiểu là các tệp thông thường cho sed hoạt động.

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