Hapus data antara dua baris inklusif

Apa cara terbaik untuk mencari dan menghapus data di antara dua baris teks, termasuk baris pertama tetapi bukan baris kedua.

String 1: SECTION - PAY 500 - untuk dihapus

data yang akan dihapus, baris teks acak

Tali 2: SECTION - Pay 400 - tinggal

Ini adalah dokumen Word yang panjangnya sekitar 3000 halaman, tetapi saya juga memiliki versi teks untuk digunakan. Di mana saya mulai menulis skrip bash untuk tugas seperti itu?

contoh isi file:

text 
SECTION - PAY 500    (to be deleted)
text                 (to be deleted)
SECTION - Pay 400
text 
SECTION - PAY 500    (to be deleted)
text                 (to be deleted)
SECTION - Pay 400
text 

Setelah dihapus, ini akan menjadi hasilnya

text 
SECTION - Pay 400
text
SECTION - Pay 400
text

person eveo    schedule 28.12.2012    source sumber
comment
Dengan asumsi Anda ingin menghapus banyak blok dari dokumen 3000 halaman Anda, dapatkah Anda memberi kami beberapa contoh lagi. Berapa banyak blok yang ingin Anda hapus? Apakah akan ada ambiguitas antara teks di penanda bagian, yaitu SECTION - PAY 5000 ? Semoga beruntung.   -  person shellter    schedule 29.12.2012
comment
sed akan menjadi tujuan saya ke sini.   -  person squiguy    schedule 29.12.2012


Jawaban (4)


Solusi dengan standar sed:

sed "/$START/,/$END/ { /$END/"'!'" d; }"

Artinya untuk rentang yang dimulai pada /$START/ dan berakhir pada /$END/ akan dilakukan tindakan { /$END/! d; }, yaitu d (menghapus) untuk semua baris yang bukan /$END/.

"'!'" memang aneh, tetapi satu-satunya cara untuk menghindari simbol ! dari ekspansi bash.

person Dmytro Sirenko    schedule 28.12.2012

Saya rasa Anda dapat mengurai file baris demi baris dengan cukup cepat. Apa yang ingin Anda arsipkan sepertinya tidak terlalu rumit untuk diwujudkan.

copy=true
while read line; do
    if [ $copy ]; then
        if [[ "$line" == "SECTION - PAY 500"* ]]; then copy=; continue; fi
        echo "$line" >> outputfile
    else
        if [[ "$line" == "SECTION - Pay 400"* ]]; then copy=true; fi
    fi
done < inputfile

Dan dengan melakukan hal ini, kita bahkan mempunyai sesuatu seperti mesin turing kecil sekarang!

person J. Katzwinkel    schedule 29.12.2012

Solusi sed standar lainnya (yang tidak terlalu aneh;)): sed "/$END/ p; /$START/,/$END/ d;"

Catatan tambahan: versi sed tertentu juga mendukung pengeditan file di tempat, jika diperlukan.

Dan skrip bash lengkap:

#! /bin/bash

if [ "x$1" = "x-r" ]
then
    regex=1
    shift
else
    regex=0
fi

if [ $# -lt 2 ]
then
    echo "Usage: del.sh [-r] start end"
    exit 1
fi

start="$1"
end="$2"

function matches
{
    [[ ( regex -eq 1 && "$1" =~ $2 ) || ( regex -eq 0 && "$1" == "$2" ) ]]
}

del=0
while read line
do
    # end marker, must be printed
    if matches "$line" "$end"
    then
        del=0
    fi
    # start marker, must be deleted
    if matches "$line" "$start"
    then
        del=1
    fi
    if [ $del -eq 0 ]
    then
        echo "$line"
    fi
done
person Jester    schedule 29.12.2012

Solusi Sederhana : Coba cara ini

Inputfile.txt

text 
SECTION - PAY 500    
text                 
SECTION - Pay 400
text 
SECTION - PAY 500   
text                 
SECTION - Pay 400
text

Kode

awk '/500/{print;getline;next}1' Inputfile.txt | sed '/500/d'

Keluaran

text 
SECTION - Pay 400
text 
SECTION - Pay 400
text 
person Debaditya    schedule 29.12.2012