liên quan đến sed di động -e db db hoặc! b?


12

Trong chỉnh sửa này, Stéphane Chazelas POSIXifying (một lần nữa)sed định dạng của tôi bằng cách chèn dấu -engắt xpression và một -ecâu lệnh xpression khác . Bây giờ, tôi có thể hỏi anh ấy tại sao trong các bình luận, tôi cho rằng, nhưng nó đã được sửa đổi số 18 trong câu trả lời đó và hầu hết tất cả những câu hỏi trước đều nhờ vào các phần mềm miễn phí tương tự (nếu bạn có thể thấy các bình luận đã xóa, bạn sẽ biết gì Ý tôi là) . Ngoài ra, tôi nghĩ rằng tôi gần đủ để hiểu tại sao phải diễn đạt điều này theo cách có thể hữu ích hơn. Vì vậy, đây là hy vọng ...

Tôi thường thích giữ tổng số lần nhấn của mình sed -ethành một nếu tôi có thể, nhưng tôi cũng có một ưu tiên lớn hơn cho việc tuân thủ thông số kỹ thuật gần nhất có thể, đặc biệt là khi chênh lệch lên tới không quá a <space>và an -e. Nhưng tôi không thể làm điều này nếu tôi không hiểu tại sao tôi nên làm vậy. Đây là một tóm tắt ngắn gọn về tình trạng hiện tại của sự hiểu biết của tôi:

  • sự ' -e 'phá vỡ có thể thay thế cho sự phá vỡ ewline sedscript \ntrong mộtsed lệnh dòng lệnh ... Tôi thừa nhận mờ nhạt về lý do tại sao

  • cú đúp kết thúc trong một sed {chức năng} phải được đi trước bởi một \nngắt ewline như đã nêu ở đây:

    • Điều này <right-brace>sẽ được đi trước bởi một <newline>và có thể được đi trước hoặc theo sau bởi<blank> ký tự.
  • một \nđột phá ewline được tương tự cần thiết sau bất kỳ sử dụng ... a, b, c, i, r, t, w, hoặc :.

Nhưng tôi không hiểu rõ định nghĩa {hàm }liên quan đến !toán tử không như thế nào . Các đề cập duy nhất tôi tìm thấy của toán tử phủ định trong các trạng thái cụ thể:

  • Một chức năng có thể được đi trước bởi một hoặc nhiều !ký tự, trong trường hợp đó, chức năng sẽ được áp dụng nếu địa chỉ không chọn không gian mẫu.

Điều này có nghĩa là việc sử dụng một !hàm {niềng răng }? Những gì của $!lệnh - chúng nên được phân tách bằng' -e ' ngắt không? Đây có phải là những gì đã được giải quyết khi Stéphane gần đây nhất là POSIXified câu trả lời của tôi?

Tôi nghĩ đó là !toán tử phủ định hoặc đó là bcâu lệnh trang trại mà anh ấy xử lý trong bản chỉnh sửa của mình - hoặc có thể là cả hai cùng một lúc - nhưng tôi không biết và nên thích. Nếu đó là chỉ những btuyên bố trang trại, sau đó tôi tin rằng một dsẽ làm ở chỗ của nó và loại bỏ sự cần thiết của các ' -e 'giờ nghỉ, nhưng tôi thà nhất định trước khi hazarding một ba lần POSIXified câu trả lời. Bạn có thể giúp?

Tôi đã có nguy cơ nó sau khi tất cả , nhưng không phải với bất kỳ sự chắc chắn tuyệt vời ...


Với b;n;:b, bạn đang phân nhánh nhãn được gọi ";n;:b"trong seds POSIX và lịch sử (và GNU sed không liên quan đến điều đó).
Stéphane Chazelas

@ StéphaneChazelas - Tôi nhận được :một phần - bạn đã lái xe về nhà cách đây nhiều tháng. Nhưng tôi không hoàn toàn hiểu tại sao sedlệnh thứ hai tương tự POSIXified .
mikeerv

1
Trong mọi trường hợp, thông số POSIX cho sedtôi rất không rõ ràng. Tôi đã yêu cầu làm rõ một vài lần trong quá khứ, nhưng tôi không nghĩ rằng nó đã được cập nhật. Một thử nghiệm tốt là thử với công cụ gia truyền (Solaris, có nguồn gốc từ bản gốc và thông số kỹ thuật POSIX chủ yếu dựa vào).
Stéphane Chazelas

1
@syntaxerror - Tôi không tin đó là trường hợp nào cả. nếu bạn đọc thông số kỹ thuật, bạn sẽ thấy rằng các s///ubstitutions được chấp nhận xâu chuỗi với a ; . nó bị mờ xung quanh các lệnh phải được phân định bằng một dòng mới và làm thế nào -ecó thể đứng trong trường hợp đó - ít nhất là đối với tôi. Tôi đã không vấp ngã trên một sedđiều mà không giải thích chúng khá thay thế cho nhau.
mikeerv

1
@syntaxerror - Tôi thích nó, nhưng bạn nên biết rằng bạn không cần ;trước một dòng mới - một dòng mới là tốt. Thành thật mà nói, bạn có thể làm mà không cần -evà hoàn toàn và chỉ viết một tệp như #!/bin/sedvới mỗi lệnh trên một dòng mới - hoặc những lệnh không yêu cầu các dấu phân cách như vậy thay vào đó được phân định bằng ;. Những người làm đòi hỏi dòng mới thường là những người đi đầu vào tùy ý - :tên nhãn và lệnh giới thiệu cho họ như bhoặc thoặc đóng }curlies cho các chức năng, hoặc read và wnghi thức mà mất args filename. Tất cả đều cần phải được theo sau \n.
mikeerv

Câu trả lời:


4

Vì vậy, đã đến lúc câu hỏi này có câu trả lời, và mặc dù cuối cùng tôi đã trực giác tìm ra cách làm điều này một cách chính xác trong mọi trường hợp cách đây một thời gian, tôi chỉ mới gần đây hiểu được cách hiểu cụ thể về văn bản trong tiêu chuẩn . Nó thực sự đã được nêu ở đó khá đơn giản - tôi chỉ ngu ngốc bỏ qua nó nhiều lần, tôi đoán vậy.

Các phần có liên quan của văn bản đều được tìm thấy dưới tiêu đề ...

  • Các lệnh chỉnh sửa trongsed :

    • Văn bản đối số sẽ bao gồm một hoặc nhiều dòng. Mỗi \newline được nhúng trong văn bản sẽ được bắt đầu bằng \dấu gạch chéo ngược. Các dấu gạch chéo ngược khác trong văn bản sẽ bị xóa và ký tự sau sẽ được xử lý theo nghĩa đen.

    • Các động từ rwlệnh, và wcờ cho slệnh, lấy tham số rfile (hoặc wfile ) tùy chọn , được phân tách từ ký tự động từ lệnh hoặc cờ bằng một hoặc nhiều <blank>s; việc triển khai có thể cho phép phân tách bằng 0 như một phần mở rộng.

    • Lệnh động từ khác hơn {, a, b, c, i, r, t, w, :, và #có thể được theo sau bởi một ;dấu chấm phẩy, không bắt buộc <blank>s, và một động từ lệnh. Tuy nhiên, khi sđộng từ lệnh được sử dụng với wcờ, theo sau nó bằng một lệnh khác theo cách này sẽ tạo ra kết quả không xác định.

...trong...

  • Tùy chọn: Nhiều -e-ftùy chọn có thể được chỉ định. Tất cả các lệnh sẽ được thêm vào tập lệnh theo thứ tự được chỉ định, bất kể nguồn gốc của chúng.

    • -e tập lệnh - Thêm các lệnh chỉnh sửa được chỉ định bởi đối số tùy chọn tập lệnh vào cuối tập lệnh của các lệnh chỉnh sửa. Đối số tùy chọn tập lệnh sẽ có cùng thuộc tính với toán hạng tập lệnh , được mô tả trong phần OPERANDS .

    • -f script_file - Thêm các lệnh chỉnh sửa trong tệp script_file vào cuối tập lệnh.

Và cuối cùng trong ...

  • Toán hạng:

    • script - Một chuỗi được sử dụng làm kịch bản lệnh chỉnh sửa. Ứng dụng sẽ không trình bày một tập lệnh vi phạm các hạn chế của tệp văn bản ngoại trừ ký tự cuối cùng không cần phải là một \newline.

Vì vậy, khi bạn thực hiện nó hoàn toàn, có nghĩa là bất kỳ lệnh nào được tùy ý theo sau bởi một tham số tùy ý mà không có dấu phân cách được xác định trước ( s d sub d repl d flagví dụ như trái ngược ) sẽ phân định tại một dấu không được giải quyết\n ewline không được giải mã.

Có thể lập luận rằng đó ; một dấu phân cách được xác định trước, nhưng trong trường hợp đó, sử dụng ;cho bất kỳ [aic]lệnh nào sẽ yêu cầu một trình phân tích cú pháp riêng biệt được đưa vào triển khai cụ thể cho ba lệnh đó - [:brw]ví dụ , riêng biệt từ trình phân tích cú pháp được sử dụng cho . Hoặc nếu không thực hiện sẽ phải yêu cầu ; cũng có dấu chéo ngược thoát trong văn bản thông số và nó chỉ mọc phức tạp hơn từ đó về.

Nếu tôi đang viết một sedcái mà tôi muốn vừa tuân thủ vừa hiệu quả, thì tôi sẽ không viết một trình phân tích cú pháp riêng biệt như vậy, tôi mong đợi - ngoại trừ việc có thể [aic]gây ra lỗi cú pháp nếu không được theo sau bởi một \newline. Nhưng đó là một vấn đề mã thông báo đơn giản - trường hợp dấu phân cách cuối thường là vấn đề khó giải quyết hơn. Tôi sẽ chỉ viết nó như vậy:

sed -e w\ file\\ -e one -e '...;and more commands'

... và ...

sed -e a\\ -e appended\\ -e text -e '...;and more commands'

... sẽ hành xử rất giống nhau, trong đó người đầu tiên sẽ tạo và ghi vào một tệp có tên:

file
one

... và thứ hai sẽ nối một khối văn bản vào dòng hiện tại trên đầu ra như ...

appended
text

... bởi vì cả hai sẽ chia sẻ cùng một mã phân tích cú pháp cho tham số.

Và liên quan đến { ... }$!vấn đề - tốt, tôi đã rời khỏi đó. Một lệnh duy nhất đứng trước một địa chỉ không phải là một chức năng mà nó chỉ là một lệnh được đánh địa chỉ. Hầu như tất cả các lệnh - bao gồm { định nghĩa hàm } được chỉ định để chấp nhận /one/hoặc /one/,/two/địa chỉ - ngoại trừ #nhận xét:định nghĩa nhãn . Và một địa chỉ có thể là số dòng hoặc một biểu thức thông thường và có thể bị phủ định !. Vậy tất cả ...

$!d
/address/s/ub/stitution/
5!y/d/c/

... có thể được theo sau bởi một ;và nhiều lệnh theo tiêu chuẩn, nhưng nếu cần nhiều lệnh hơn cho một địa chỉ duy nhất và địa chỉ đó không nên được đánh giá lại sau khi thực hiện từng lệnh, thì nên sử dụng một {hàm }như:

/address/{ s//replace addressed pattern/
           s/do other conditional/substitutions/
           s/in the same context/without/
           s/reevaluating/address/
}

... trong trường hợp {không thể theo dõi trên cùng một dòng bằng cách đóng }và việc đóng }có thể xảy ra ngoại trừ khi bắt đầu một dòng. Nhưng nếu một lệnh được chứa không nên được theo sau bởi một \newline, thì nó cũng không cần trong hàm. Vì vậy, tất cả các s///ubstitutions ở trên - và thậm chí cả niềng răng đóng cửa }, có thể được theo sau một cách hợp lý; dấu chấm phẩy và các lệnh tiếp theo.

Tôi tiếp tục nói về các \ndấu phân cách ewline nhưng câu hỏi thay vào đó là về các -ecâu lệnh xpression, tôi biết. Nhưng hai cái này thực sự là một và giống nhau, và mối quan hệ chính là một tập lệnh có thể là một đối số dòng lệnh hoặc một tệp với một trong hai -[ef]và cả hai đều được hiểu là các tệp văn bản (được chỉ định để kết thúc bằng một \newline) nhưng không thực sự cần kết thúc trong một \newline. Bằng cách này, tôi có thể reasonbly (Tôi hy vọng) suy luận rằng một \0NULlập luận phân ngụ ý một kết thúc \newline, và như tất cả các đối số gọi được ít nhất) một \0NULdelimiter dù sao, sau đó, hoặc sẽ làm việc tốt.

Trong thực tế, trong thực tế, trong mọi trường hợp ngoại trừ một tiêu chuẩn chỉ định một \dấu gạch chéo ngược thoát dòng mới cần phải có, tôi đã tìm thấy ...

sed -e ... -e '...\' -e '...'

... Làm việc tốt như vậy. Và trong mọi trường hợp - một lần nữa, trong thực tế - nơi cần có một \newline không thoát ...

sed -e '...' -e '...'

... cũng đã làm việc cho tôi. Một ngoại lệ tôi đề cập ở trên là ...

sed -e 's/.../...\' -e '.../'

... mà không hoạt động cho bất kỳ thực hiện trong bất kỳ thử nghiệm của tôi. Tôi khá chắc chắn rằng nó quay trở lại yêu cầu tệp văn bản và thực tế s/// đi kèm với một dấu phân cách và vì vậy không có lý do gì một câu lệnh nên kéo dài\0NUL đối số được phân tách.

Vì vậy, kết luận, đây là một bản tóm tắt ngắn gọn về các cách di động để viết một số loại sed lệnh:

Đối với bất kỳ [aic]:

...commands;[aic]\
text embedded newline\
delimiting newline
...more;commands...

...hoặc là...

sed -e '...commands;[aic]\' -e 'text embedded newline\' -e 'delimiting newline' -e '.;.;.'

Đối với bất kỳ [:rwtb]nơi nào tham sốtùy chọn (cho tất cả nhưng :) nhưng \newline phân định thì không . Lưu ý rằng tôi chưa bao giờ có lý do để thử nhiều tham số nhãn dòng như được sử dụng [:tb], nhưng việc wtrích dẫn / rgợi ý nhiều dòng trong tham số tệp [rw] thường được chấp nhận mà không có câu hỏi nào bởi sedtôi đã kiểm tra miễn là \newline nhúng được thoát với \dấu gạch chéo ngược. Tuy nhiên, tiêu chuẩn không trực tiếp chỉ định các tham số tệp nhãn[rw] đó các tham số phải được phân tích cú pháp giống hệt thành văn bản và không đề cập đến\newlines liên quan đến hai cái đầu tiên trừ khi nó phân định chúng.

...commands;[:trwb] parameter
...more;commands...

...hoặc là...

sed -e '[:trwb] parameter' -e '...'

... Trong đó <space>ở trên là tùy chọn cho [:tb].

Và cuối cùng...

...;address[!]{ ...function;commands...
};...more;commands....

...hoặc là...

sed -e '...;address[!]{ ...function;commands...' -e '};...more;commands...'

... Trong đó bất kỳ lệnh nào đã nói ở trên (ngoại trừ :) cũng chấp nhận ít nhất một địa chỉ và có thể là biểu /thức chính quy /hoặc số dòng và có thể bị từ chối !, nhưng nếu cần nhiều hơn một lệnh cho một đánh giá địa chỉ thì {chức năng }phân định bối cảnh chức năng phải được sử dụng. Một hàm có thể chứa nhiều \nlệnh được phân tách bằng ewline, nhưng mỗi lệnh phải được phân cách trong dấu ngoặc nhọn nếu không.

Và đó là cách viết sedkịch bản di động .


2
Tại sao bạn không chấp nhận câu trả lời của riêng bạn?
Philippos
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.