2012-11-21 26 views
6

Tôi đang chạy sed như một phần của tập lệnh trình bao để xóa nhật ký ràng buộc để chèn vào cơ sở dữ liệu.Hạn chế SED thành 10 ký tự đầu tiên của dòng

Một trong những lệnh sed như sau:

sed -i 's/-/:/g' $DPath/named.query.log 

này hóa ra là có vấn đề vì nó phá vỡ bất kỳ yêu cầu tài nguyên mà cũng bao gồm một dấu gạch ngang (Tôi đang sử dụng: là một dấu phân cách cho một tuyên bố awk tiếp tục xuống).

Câu hỏi của tôi là làm cách nào để giới hạn lệnh sed ở trên chỉ còn mười ký tự đầu tiên của dòng? Tôi đã không nhìn thấy một chuyển đổi cụ thể mà làm điều này, và tôi là hư không gần đủ tốt với RegEx thậm chí bắt đầu phát triển một trong đó hoạt động. Tôi không thể sử dụng regex để phù hợp với các số trước bởi vì có thể mẫu đó có thể là một phần của yêu cầu tài nguyên. Heck, tôi thậm chí không thể sử dụng kết hợp mẫu cho #### - ## - ## bởi vì, một lần nữa, nó có thể là một phần của tài nguyên.

Bất kỳ ý tưởng nào được đánh giá cao.

Trả lời

2

Đó là [hầu như luôn luôn] đơn giản với awk:

awk '{target=substr($0,1,10); gsub(/-/,":",target); print target substr($0,11)}' file 
+0

Thưa ông, tôi nghĩ rằng sẽ làm điều đó. Cảm ơn nhiều! – MikeH

+2

Hoặc thậm chí (chưa được kiểm tra) 'perl -pe 'substr ($ _, 0, 10) = ~ s /:/-/g' file' – tripleee

+0

@tripleee: Nhận xét của bạn (chưa được kiểm tra) không hoạt động đối với tôi (nhưng tôi không biết perl). –

0

Bạn có thể làm như sau:

cut -c 1-10 $DPath/named.query.log | sed -i 's/-/:/g' 

Các statemnt cắt chỉ mất 10 ký tự đầu tiên của mỗi dòng trong tập tin đó. Đầu ra của nó nên được đặt trong một tập tin. Tính đến bây giờ nó sẽ chỉ ra cho thiết bị đầu cuối của bạn

+2

Tôi nghĩ rằng OP muốn sửa đổi "-" s chỉ trong 10 ký tự đầu tiên của một dòng lâu hơn, không cắt dòng 10 ký tự và sau đó sửa đổi tất cả " -"S. Ngoài ra, tôi tự hỏi những gì sed của "-i" sẽ làm gì với không có tập tin để sửa đổi .... –

1

Tôi không chắc chắn như thế nào làm cho sed làm điều đó mỗi gia nhập, tuy nhiên, tôi biết rằng bạn có thể ăn sed 10 ký tự đầu tiên sau đó dán phần còn lại trở lại, như vậy:

paste -d"\0" <(cut -c1-10 $DPath/named.query.log | sed 's/\-/:/g') <(cut -c11- $DPath/named.query.log)

+0

Điều này kích hoạt đầu ra trên màn hình chứ không phải vào tập tin, nhưng điều này có thể làm việc là tốt.Cảm ơn bài viết. :) – MikeH

2

tôi nghĩ rằng giải pháp ngắn nhất, và có lẽ là đơn giản nhất, được cung cấp bởi sed chính nó, chứ không phải là awk [phường]:

sed "h;s/-/:/g;G;s/\(..........\).*\n........../\1/" 

Giải thích:

  • (h) sao chép tất cả mọi thứ để không gian giữ
  • (s) làm thay (cho toàn bộ không gian mẫu)
  • (G) nối thêm không gian tổ chức, với a \n separator
  • (s) xóa các ký tự lên đến phần mười sau \n, nhưng giữ mười ký tự đầu tiên.

Một số mã kiểm tra:

echo "--------------------------------" > foo 
sed -i "h;s/-/:/g;G;s/\(..........\).*\n........../\1/" foo 
cat foo 
::::::::::---------------------- 
+1

Tốt! Có lẽ một chút cải thiện 'sed' h; y/- /: /; G; s/^ \ (. \ {10 \} \). * \ N. \ {10 \}/\ 1/'' – potong

+0

@potong : Vâng, bạn đúng. * Nhưng * một số hệ thống cũ không hỗ trợ cú pháp này. * Và * nó ít rõ ràng hơn. –

+0

@potong: Nhưng giải pháp của bạn là * ngắn hơn * so với tôi, bằng bảy ký tự (bỏ qua những thứ không cần thiết ^). 'Y' đã lưu một ký tự. –

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