2011-07-08 23 views
5

Tôi muốn thay đổi định dạng của mỗi dòng trong một tệp và cũng có thể chạy một thay thế khác trên một trong các nhóm phù hợp.Có cách nào để tổ chức thay thế sed?

Ví dụ: tôi có thể có tệp CSV ba cột đơn giản (không có thoát) mà tôi muốn đặt ở định dạng khác.

sed -r 's/^([a-z]+),([a-z]+),([a-z]+)$/\1: \3 (\2)' 
# would turn "comma,separated,values" 
# into  "comma: values (separated)" 

Tuy nhiên, tôi cũng muốn loại bỏ tất cả các nguyên âm từ cột thứ hai, ví dụ: chạy s/[aeiou]//g trên \2.

Có giải pháp tốt cho vấn đề thay thế lồng ghép này không? Hãy giả sử rằng cả hai thay thế đều phức tạp và đây chỉ là một ví dụ.

Sed của tôi không phải là GNU sed phiên bản 4.0.

+0

Bạn có thể không hút một sed vào thứ hai không? – NorthGuard

+0

@inTide: Tôi không muốn xóa _all_ nguyên âm, chỉ những nguyên từ cột thứ hai. – Tim

+0

Phải, vì vậy trước tiên bạn loại bỏ tất cả các nguyên âm giữa dấu phẩy và sed thứ hai bạn tạo dấu phẩy đầu tiên ':' và dấu phẩy thứ hai '()'. – NorthGuard

Trả lời

0

Tôi nghĩ bạn nên sử dụng số awk để làm việc này dễ dàng hơn trong việc thao tác trên các trường.

echo "gaviidae,gruidae,picidae" | awk -F "," '{gsub(/[aeiou]/, "", $2); printf("%s: %s (%s)\n", $1, $3, $2)}' 

kết quả đầu ra:

gaviidae: picidae (grd) 
+0

Tôi không biết 'awk'; là có một cách đơn giản để phù hợp trong một cách tương tự như 'sed'? Lệnh của bạn dường như bị chia nhỏ thành ',', vì vậy nó không phải là rất chung chung. – Tim

+0

Dấu phân tách trường được đặt bởi đối số -F. Nó chấp nhận các biểu thức chính quy, nhưng không phải theo cách mà bạn sẽ viết chúng để sử dụng backreferences. Tôi sẽ cho rằng awk không phải là rất hữu ích nếu định dạng của bạn yêu cầu phân tích cú pháp phức tạp hơn để chia thành các trường. – Simon

1

Đây là khó hiểu (như hầu hết bất kỳ không tầm thường sed) nhưng nó sẽ thực hiện công việc. Nó tận dụng lợi thế của thực tế là bạn muốn từ sửa đổi để đi vào cuối-- lừa tương tự sẽ làm việc nếu bạn muốn nó đi đến một số vị trí khác, nhưng lệnh sẽ lâu hơn một chút.

sed 'h;s/.*,([a-z]+),.*/(\1)/;s/[aeiou]//g;x;s/([a-z]+),[a-z]+,([a-z]+)/\1: \2 /;G;s/\n//' 

Hoặc bằng tiếng Anh: "lưu một bản sao trong bộ đệm giữ, giết tất cả nhưng từ thứ hai, loại bỏ các nguyên âm, trao đổi các bộ đệm, sắp xếp lại các từ (thả giữa một), thêm bộ đệm khác vào cuối, loại bỏ dòng mới ".

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