Bagaimana cara menghapus baris jika lebih lama dari XY?


21

Bagaimana saya bisa menghapus garis jika lebih panjang dari misalnya: 2048 karakter?


Apakah Anda bersikeras menggunakan sed? Ini mudah, misalnya dengan python. Dan tidak diragukan lagi bahkan lebih mudah di perl. Padahal pertanyaannya tidak terlalu jelas. Salin file, hapus semua baris lebih dari 2048, atau yang lainnya?
Faheem Mitha

Jawaban:


22
sed '/^.\{2048\}./d' input.txt > output.txt

3
Saya mendapatkan pesan error sed: 1: "/^.\{2048\}..*/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi Anda mungkin ingin menginstal versi GNU daripada versi BSD yang dikirimkan bersama Mac. Ini mudah dengan minuman
Freedom_Ben

Pertanyaannya mengatakan "jika lebih lama dari XY (mis., 2048 karakter)". Maka itu harus> 2048 dan bukan => 2048
ajcg

1
@ajcg, Ini> 2048. Perhatikan bahwa ada periode ekstra di akhir regex untuk mencocokkan karakter 2049.
forcefsck

@forcefsck dan tidak akan lebih baik jika Anda mengambilnya "^"? (dengan perintah Anda, Anda hanya menghapus baris yang "mulai dengan XYZ", tetapi jika XYZ ada di bagian lain dari baris itu maka itu tidak akan menghapusnya)
ajcg

7

Inilah solusi yang menghapus garis yang memiliki 2049 karakter atau lebih:

sed -E '/.{2049}/d' <file.in >file.out

Ekspresi /.{2049}/dakan cocok dengan baris apa pun yang berisi setidaknya 2049 karakter dan menghapusnya dari input, hanya menghasilkan garis yang lebih pendek pada output.

Dengan awk, garis pencetakan panjang 2048 atau lebih pendek:

awk 'length <= 2048' <file.in >file.out

Meniru sedsolusi secara harfiah dengan awk:

awk 'length >= 2049 { next } { print }' <file.in >file.out

1
Saya mendapatkan pesan error sed: 1: "/^.\{400,\}$/d": RE error: invalid repetition count(s)(Mac OS X)
wedi

1
@wedi Sekarang diperbarui dan diuji pada macOS Mojave.
Kusalananda

2

Sesuatu seperti ini seharusnya bekerja dengan Python.

of = open("orig")
nf = open("new",'w')
for line in of:         
    if len(line) < 2048:
        nf.write(line)
of.close()
nf.close()

1
Secara pribadi, @Faheem, saya lebih suka jawaban Anda. Alasan mengapa itu sangat mudah bagi saya untuk mengubahnya menjadi 'hapus semua baris lebih kecil dari x'. Saya tidak menggunakan Python sepanjang waktu, tetapi ketika saya melakukannya saya selalu merasa saya harus mempelajarinya dengan baik.
ixtmixilix

@ixtmixilix: Ya, menggunakan bahasa berfitur lengkap seperti Python cukup fleksibel. Terima kasih atas komentarnya.
Faheem Mitha

2
perl -lne "length < 2048 && print" infile > outfile

+1 Tidak -ldiperlukan, meskipun.
Joseph R.

Tidak bekerja untuk saya. Perl v5.16.2. Warning: Use of "length" without parentheses is ambiguous at -e line 1. Unterminated <> operator at -e line 1.
wedi

Anda boleh mencoba length($_) > 2048 && print. lengthbagaimanapun juga adalah jalan pintas length($_).
MaratC

0

Jawaban di atas tidak berfungsi untuk saya di Mac OS X 10.9.5.

Kode berikut ini berfungsi:

sed '/.\{2048\}/d'.

Meskipun tidak diminta, tetapi disediakan untuk referensi, kebalikannya dapat dicapai kode berikut:

sed '/.\{2048\}/!d'.


lol, tapi sed: 1: "/.\{2048\}/d": RE error: invalid repetition count(s)( Mac OS X, 10.10.4)
alex grey

Ah. Saya menginstal versi GNU, bukan versi BSD yang dikirimkan bersama Mac seperti yang disarankan @Freedom_Ben di atas. Tetapi Kusalananda menemukan peralihan untuk mengaktifkan regex yang diperluas. Jadi, Anda harus pergi dengan solusinya jika Anda masih memiliki masalah itu. ;)
wedi

0

Dengan gnu-sed, Anda dapat menggunakan flag -r, untuk menghindari mengetik garis miring terbalik, dan koma, untuk menentukan interval terbuka:

sed -r  "/.{2049,}/d" input.txt > output.txt

dengan:

  • x {2049} artinya persis 2049 xs
  • x {2049,3072} artinya dari 2049 hingga 3072 xs
  • x {2049,} artinya setidaknya 2049 xs
  • x {, 2049} artinya paling banyak 2049 xs

Untuk interval, agar tidak cocok dengan pola yang lebih besar, Anda akan memerlukan jangkar garis seperti

sed -r  "/^.{32,64}$/d" input.txt > output.txt 
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.