Lakukan operasi sed pada nomor baris yang diberikan

8

Saya bertanya-tanya apakah ada cara sederhana untuk beroperasi pada jalur tertentu dengan nomor baris yang sudah ditentukan sebelumnya.

Katakanlah saya ingin menampilkan 1, 7, 14 dan 16 baris file, saya bisa lakukan

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

tetapi ini menjadi lebih rumit ketika operasi tidak hanya mencetak, dan saya tidak ingin menulis perintah panjang yang sama 4 kali (dan ya, saya tahu saya bisa membangun perintah sed lama ini dengan mengganti variabel bash yang sama 4 kali, tetapi itu tidak cukup ideal ...), yaitu

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

Apakah ada cara untuk melakukan operasi pada baris spesifik file saya ini? Saya mengharapkan sesuatu seperti,

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

yang pasti tidak akan berfungsi dalam bentuk saat ini.

Bantuan apa pun akan dihargai. "Tidak, itu tidak mungkin." dengan penjelasan juga merupakan jawaban yang akan saya terima.

Weijun Zhou
sumber
mudah denganawk
RomanPerekhrest

Jawaban:

11

Anda dapat menggunakan cabang:

sed '
  1b1
  7b1
  14b1
  16b1

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

  :1
  long_command'

(perhatikan bahwa Anda juga dapat menambahkan beberapa 20,25b1rentang garis, atau /re/b1untuk memasukkan garis yang cocok dengan re).

Atau Anda bisa menggunakan awk:

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

Atau menggunakan hash:

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

  NR in lines {stuff}'

(atau BEGIN{lines[1]lines[7]lines[14]lines[16]}jika tidak terlalu banyak)

Stéphane Chazelas
sumber
Terima kasih, tidak pernah memikirkan cabang ... Sepertinya alat yang ideal untuk digunakan dalam kasus ini.
Weijun Zhou
bagaimana cara menggunakan cabang seperti ini di sed dengan pola pencarian? seperti mengatakan saya ingin mencocokkan atau menghapus pola setelah baris ke-n?
qodeninja
3

Cukup batalkan pilihan Anda dan hapus:

sed '2,6d;8,13d;15d;17,$d;long_command'
Filipos
sumber
Ini juga merupakan solusi yang bagus walaupun sedikit lebih sulit untuk menangani nomor baris yang dibaca dari stdin, misalnya.
Weijun Zhou
1

Varian pertama:

Anda dapat menggunakan trik ini:

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

-f script-file - tambahkan konten file skrip ke perintah yang akan dieksekusi.

Pengujian

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

Keluaran

1
7
14
16

Varian kedua:

Pada awalnya, auxiliary seddigunakan untuk memfilter hanya baris-baris yang diperlukan dari file, kemudian baris-baris ini disalurkan ke main seddengan perintah panjang.

sed -n '1p; 7p; 14p; 16p' input.txt | sed 'long command'
MiniMax
sumber