2011-06-23 24 views
9

Trong awk tôi có thể viết: awk -F: 'BEGIN {OFS = FS} ...'biến cho tách trường trong perl

Trong Perl, tương đương với FS là gì? Tôi muốn viết

perl -F: -lane 'BEGIN {$, = [what?]} ...' 

cập nhật với một ví dụ:

echo a:b:c:d | awk -F: 'BEGIN {OFS = FS} {$2 = 42; print}' 
echo a:b:c:d | perl -F: -ane 'BEGIN {$, = ":"} $F[1] = 42; print @F' 

Cả hai đầu ra a:42:c:d

Tôi không muốn cứng mã : trong khối Perl BEGIN , nhưng hãy tham khảo bất cứ nơi nào tùy chọn -F lưu đối số của nó.

+0

Tôi không quen với awk ... bạn có thể cung cấp ví dụ về những gì bạn đang cố gắng thực hiện với perl không? Tôi có lẽ có thể trả lời tốt hơn câu hỏi awl-> perl. Tôi thu thập rằng OFS là phân tách trường đầu ra (mà bạn đã xác định chính xác là $, trong perl), và FS là đầu vào? phân tách trường? Tôi không nghĩ rằng perl có một khái niệm như vậy ... mặc dù có thể chức năng split() là tương tự, tuy nhiên nó không có một "bộ phân tách" mặc định - nó phải được cung cấp trực tiếp. – Flimzy

+0

@Flimzy, câu hỏi được cập nhật –

+0

Tham số tới '-F' thực sự là một regex, không phải là chuỗi ký tự, vì vậy tôi không nghĩ rằng nó có thể truy cập trực tiếp bằng bất kỳ biến đặc biệt nào. – friedo

Trả lời

6

Tóm lại, những gì tôi đang tìm kiếm không tồn tại:

  1. không có biến chứa các đối số cho -F, và quan trọng hơn
  2. Perl của "FS" về cơ bản là một loại dữ liệu khác (biểu thức chính quy) so với "OFS" (chuỗi) - nó không có ý nghĩa để tham gia một danh sách các chuỗi bằng cách sử dụng một regex.

Lưu ý rằng điều này vẫn đúng trong awk: FS là một chuỗi nhưng đóng vai trò như regex:

echo a:b,c:d | awk -F'[:,]' 'BEGIN {OFS=FS} {$2=42; print}' 

đầu ra "a[:,]42[:,]c[:,]d"

Cảm ơn vì sự hiểu biết và cách giải quyết mặc dù.

2

Nếu bạn biết chiều dài chính xác của đầu vào, bạn có thể làm điều này:

echo a:b:c:d | perl -F'(:)' -ane '$, = $F[1]; @F = @F[0,2,4,6]; $F[1] = 42; print @F' 

Nếu đầu vào là có độ dài thay đổi, bạn sẽ cần một cái gì đó phức tạp hơn @f [0,2,4, 6].

EDIT: -F dường như chỉ đơn giản là cung cấp đầu vào cho một cuộc gọi split() tự động, lấy RE hoàn chỉnh làm biểu thức. Bạn có thể tìm thấy điều gì đó phù hợp hơn bằng cách đọc các mục nhập perldoc cho chia, perlreperlvar.

0

Không có bộ tách bản ghi đầu vào nào trong Perl. Về cơ bản, bạn đang mô phỏng awk bằng cách sử dụng các cờ -a-F. Nếu bạn thực sự không muốn mã cứng giá trị, thì tại sao không chỉ sử dụng biến môi trường?

$ export SPLIT=":" 
$ perl -F$SPLIT -lane 'BEGIN { $, = $ENV{SPLIT}; } ...' 
1

Darnit ...

Điều tốt nhất tôi có thể làm là:

echo a:b:c:d | perl -ne '$v=":";@F = split("$v"); $F[1] = 42; print join("$v", @F) . "\n";' 

Bạn không cần -F: cách này, và bạn chỉ nêu ruột kết một lần. Tôi đã hy vọng có một cách nào đó của việc thiết lập các biến trên dòng lệnh như bạn có thể với công tắc -v của Awk.

Đối với một lớp lót, Perl thường không sạch như Awk, nhưng tôi nhớ sử dụng Awk trước khi tôi biết về Perl và viết 1000 dòng Awk script.

Thử những thứ như thế này khiến mọi người nghĩ Awk đã được đặt tên theo âm thanh của người nào đó khi họ cố gắng giải mã tập lệnh đó hoặc đứng cho AWKward.

+0

Tôi đã đi một chuyến đi xuống làn đường bộ nhớ, và nó đánh tôi * có thể * thiết lập các biến từ dòng cmd: với hack 's' chuyển đổi:' echo a: b: c: d | perl -sne '@F = split ("$ sep"); $ F [1] = 42; in tham gia ("$ sep", @F). "\ n"; ' - -sep =: ' –

1

Bạn có thể loại lừa nó, bởi vì perl được thực sự sử dụng split chức năng với -F lập luận của bạn, và bạn có thể nói split để bảo tồn những gì nó chia tách trên bằng cách bao gồm dấu ngoặc chụp trong regex:

$ echo a:b:c:d | perl -F'(:)' -ane 'print join("/", @F);' 
a/:/b/:/c/:/d 

Bạn có thể xem những gì của perl làm với một số trong những "kỳ diệu" đối số dòng lệnh bằng cách sử dụng -MO=Deparse, như thế này:

$ perl -MO=Deparse -F'(:)' -ane 'print join("/", @F);' 
LINE: while (defined($_ = <ARGV>)) { 
    our(@F) = split(/(:)/, $_, 0); 
    print join('/', @F); 
} 
-e syntax OK 

Bạn 'd phải thay đổi số đăng ký @F để tăng gấp đôi số lượng bình thường ($F[2] = 42).

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