2

最初の行を含み、2 番目の行を含まない 2 行のテキスト間のデータを検索および削除する最良の方法は何でしょうか。

文字列 1: SECTION - PAY 500- 削除する

削除するデータ、ランダムなテキスト行

文字列 2: SECTION - Pay 400- 滞在

これは約 3000 ページのワード文書ですが、テキスト バージョンも使用しています。そのようなタスクのための bash スクリプトをどこから書き始めればよいでしょうか?

ファイル内容の例:

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 

削除後、これが結果になるはずです

text 
SECTION - Pay 400
text
SECTION - Pay 400
text
4

4 に答える 4

3

標準のソリューションsed:

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

これは、 で開始し/$START/て で終了する範囲に対して/$END/アクション{ /$END/! d; }が実行されることを意味し、 でdはないすべての行に対して (削除) を行います/$END/

"'!'"は奇妙ですが、!bash 展開からシンボルをエスケープする唯一の方法です。

于 2012-12-28T23:55:45.760 に答える
0

簡単な解決策:この方法を試してください

Inputfile.txt

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

コード

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

出力

text 
SECTION - Pay 400
text 
SECTION - Pay 400
text 
于 2012-12-29T17:58:09.440 に答える
0

ファイルを1行ずつ非常に迅速に解析できると思います。アーカイブしようとしていることは、複雑すぎて実現できないようには見えません。

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

そうすることで、今では小さなチューリング マシンのようなものさえあります。

于 2012-12-29T00:00:46.080 に答える
0

別の(それほど奇妙ではありません;))標準のsedソリューション: sed "/$END/ p; /$START/,/$END/ d;"

補足: 特定のsedバージョンでは、必要に応じてファイルのインプレース編集もサポートされています。

そして本格的な bash スクリプト:

#! /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
于 2012-12-29T00:13:34.760 に答える