2017-07-23 14 views
6

Mục nhập của tôi có kết hợp các tab và dấu cách để dễ đọc. Tôi muốn sửa đổi một trường bằng cách sử dụng perl -a, sau đó in ra dòng ở dạng ban đầu của nó. (. Các dữ liệu là từ findup, thể hiện cho tôi một số các tập tin trùng lặp và không gian mà họ lãng phí) Input là:Có thể "perl -a" bằng cách nào đó tham gia lại @F bằng cách sử dụng khoảng trắng ban đầu không?

2 * 4096 backup/photos/photo.jpg photos/photo.jpg 
2 * 111276032 backup/books/book.pdf book.pdf 

Kết quả sẽ chuyển đổi lĩnh vực từ 3 đến kilobyte, như thế này:

2 * 4 KB backup/photos/photo.jpg photos/photo.jpg 
2 * 108668 KB backup/books/book.pdf book.pdf 

trong thế giới giấc mơ của tôi, đây sẽ là mã của tôi, vì tôi chỉ có thể sẽ perl để tự động tái kết hợp @F và giữ gìn khoảng trắng gốc:

perl -lanE '$F[2]=int($F[2]/1024)." KB"; print;' 

trong thực cuộc sống, tham gia với một không gian duy nhất có vẻ như là lựa chọn duy nhất của tôi:

perl -lanE '$F[2]=int($F[2]/1024)." KB"; print join(" ", @F);' 

Có biến tự động nào ghi nhớ các dấu phân tách không? Nếu tôi có một mảng ma thuật như vậy, mã sẽ là:

perl -lanE 'BEGIN{use List::Util "reduce";} $F[2]=int($F[2]/1024)." KB"; print reduce { $a . shift(@magic) . $b } @F;' 
+2

Btw, in với một không gian giữa các yếu tố: 'print "@F";' – zdim

Trả lời

9

Không, không có đối tượng ma thuật như vậy. Bạn có thể làm điều đó bằng tay dù

perl -wnE'@p = split /(\s+)/; $p[4] = int($p[4]/1024); print @p' input.txt 

Các capturing Parens trong mẫu split 's có nghĩa là nó cũng được trả lại, vì vậy bạn bắt không gian chính xác. Vì các khoảng trống nằm trong mảng, bây giờ chúng ta cần trường thứ năm.

Khi nó quay ra, -F có cùng thuộc tính này. Cảm ơn Сухой27. Sau đó

perl -F'(\s+)' -lanE'$F[4] = int($F[4]/1024); say @F' input.txt 

Lưu ý: with 5.20.0 "-F nay ngụ ý -a-a ngụ ý -n". Nhờ có ysth.

+1

'-F' (\ s +) ''có thể được sử dụng làm tham số và' say' sẽ cung cấp thêm dòng mới. –

+1

@ Сухой27 Chà. Cảm ơn bạn. Tôi nghĩ về điều đó và "nhớ lại" rằng người ta chỉ có thể sử dụng chữ trong đó. (Tôi nghĩ rằng "hồi ức" đến từ '$ /' ...?) Đã sửa và thêm vào. – zdim

+1

@piojo Cập nhật câu trả lời - nó chỉ ra rằng có chính xác những gì bạn yêu cầu. Đồng thời sửa lỗi. – zdim

1

Bạn chỉ có thể tìm ra một phần đúng của dòng và sửa đổi nó:

perl -wpE's/^\s*+(?>\S+\s+){2}\K(\S+)/int($1\/1024) . " KB"/e' 
+4

Thoát '\' trong mã là rất kỳ quặc và tránh được bằng dấu phân cách thay thế (ví dụ: 's! ...! ...! E' hoặc' s {...} {...} e') – ikegami

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