Thực hiện các thao tác sed trên số dòng đã cho


8

Tôi tự hỏi liệu có một cách đơn giản để hoạt động trên một số dòng nhất định với số dòng được chỉ định.

Giả sử tôi muốn xuất các dòng thứ 1, 7, 14 và 16 của một tệp, tôi chỉ có thể làm

sed -n '1p;7p;14p;16p' input_file

nhưng điều này trở nên phức tạp hơn khi thao tác không chỉ in và tôi không muốn viết cùng một lệnh dài 4 lần (và vâng, tôi biết tôi có thể xây dựng lệnh sed dài này bằng cách thay thế cùng một biến bash 4 lần, nhưng điều đó không đủ lý tưởng ...), tức là

sed -n '1{long_command};7{long_command};14{long_command};16{long_command}' input_file

Có cách nào để thực hiện thao tác trên các dòng cụ thể này của tệp của tôi không? Tôi đang mong đợi một cái gì đó như,

sed -n '1,7,14,16p'

mà chắc chắn sẽ không hoạt động trong các hình thức hiện tại.

Bất kỳ trợ giúp sẽ được đánh giá cao. "Không, no không thể." với lời giải thích cũng là một câu trả lời mà tôi sẽ chấp nhận.


thật dễ dàng vớiawk
RomanPerekhrest

Câu trả lời:


11

Bạn có thể sử dụng các nhánh:

sed '
  1b1
  7b1
  14b1
  16b1

  # for the rest to be left alone, branch off (or delete them with "d"):
  b

  :1
  long_command'

(lưu ý rằng bạn cũng có thể thêm một số 20,25b1phạm vi dòng hoặc /re/b1để bao gồm các dòng khớp với re).

Hoặc bạn có thể sử dụng awk:

awk 'NR == 1 || NR == 7 || ... {stuff}'

Hoặc sử dụng hàm băm:

awk -v l=1,7,14,16 '
  BEGIN{split(l, a, ","); for (i in a) lines[a[i]]}

  NR in lines {stuff}'

(hoặc BEGIN{lines[1]lines[7]lines[14]lines[16]}nếu không có quá nhiều)


Cảm ơn bạn, không bao giờ nghĩ về các chi nhánh ... Nó dường như là công cụ lý tưởng để sử dụng trong trường hợp này.
Weijun Zhou

Làm thế nào để sử dụng các nhánh như thế này trong sed với một mẫu tìm kiếm? như nói tôi muốn khớp hoặc xóa một mẫu sau dòng thứ n?
qodeninja

3

Chỉ cần đảo ngược lựa chọn của bạn và xóa nó:

sed '2,6d;8,13d;15d;17,$d;long_command'

Đây cũng là một giải pháp tốt mặc dù khó hơn một chút để xử lý số dòng được đọc từ stdin chẳng hạn.
Weijun Zhou

1

Biến thể đầu tiên:

Bạn có thể sử dụng thủ thuật này:

sed -nf <(printf '%dp\n' 1 7 14 16)

-f script-file - thêm nội dung của tệp script vào các lệnh sẽ được thực thi.

Kiểm tra

seq 1 20 | sed -nf <(printf '%dp\n' 1 7 14 16)

Đầu ra

1
7
14
16

Biến thể thứ hai:

Ban đầu, phần phụ sedđược sử dụng để chỉ lọc các dòng cần thiết từ tệp, sau đó các dòng này được dẫn đến chính sedbằng lệnh dài.

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
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.