一度に2行ずつファイルを繰り返し、必要なカップレットをコピーするbashスクリプト

一度に2行ずつファイルを繰り返し、必要なカップレットをコピーするbashスクリプト

アクション: Bash を使用して 1 つのファイル (例: file1.txt) を一度に 2 行ずつ繰り返し、見つかった各カプラーを 2 番目のファイル (例: file2.txt) にコピーする必要があるかどうかを尋ねるメッセージ表示します。このコマンドは、grep -A 1 "searchterm" file1.txt私が探している出力タイプを提供します。したがって、スクリプトは数行ごとに繰り返す必要があり、カップレットを2番目のファイルにコピーするかどうかを尋ね、次の数行に対して同じ操作を増やし、ファイルの最後まで繰り返す必要があります。このファイルには合計4000行程度があり、そのうち400行程度を2番目のファイルにコピーしたいと思います。

ファイルの内容は次の例に似ています。

#searchterm blah
possible additional needed line 1
#searchterm blee
possible additional needed line 2
#searchterm blob
possible additional needed line 3
#searchterm bloh
possible additional needed line 4
#searchterm bluh
possible additional needed line etc

2番目のファイルにコピーすることは、ファイルの末尾に追加することによってcp >>行うことができます。私はforループおよび/またはwhileがこれに適していると思います。その漸進的な部分は、現時点では一種の脱出口です。しかし、私のbashスクリプト技術/知識はせいぜい平均レベルです。コメントありがとうございます。

後で修正 これが私が求めていることの始まりでした。https://stackoverflow.com/questions/8314499/read-n-lines-at-a-time-using-bash):

while read -r ONE; do
    read -r TWO
    echo $ONE
    echo $TWO
    sleep 3
    # replace above sleep command with command(s) that copy lines or exit back to while loop
done < file1.txt

今回は、file1.txt から 2 行を読み込み、各カプラーを端末に出力します。 sleep 3行は、「この2行をfile2.txtにコピーしますか?yまたはnで答えてください」など、ユーザーに入力を要求するいくつかのルーチンに置き換える必要があります。ユーザーがyを選択すると、次の2行がprintf $ONE >>file2.txt && printf $TWO >>file2.txt返されます。while行ループの前に同様の操作が実行されます。ユーザーがnと答えると、ループは最後に停止した場所に戻り、file1.txtの次の2行を端末に印刷して同じ質問をします。進展?

以降の編集:ソリューション全体の最初の試みは失敗しました。

while read -r ONE; do
    read -r TWO
    echo $ONE
    echo $TWO
    read -n 1 -p "Would you like to copy the above 2 lines to the new  file? [Y,n]" ans
        if [[ $ans == "Y" || $ans == "y" ]]; then
                printf $ONE >>file2.txt && printf $TWO >>file2.txt
        else
                echo "Resuming loop"
        fi
done < file1.txt

動作しません。これは、出力がcat file1.txtコマンドラインで実行するのと大きく変わらないことを意味します。しかし、多分それは私がこのシナリオを通して達成したいものが何であるかについてより良いアイデアを与えるかもしれません。

後で編集:半分実行中 さらなる調査によると、そのタスクを実行するにはファイル記述子である必要があるかもしれません。このリンクを使用してくださいhttps://stackoverflow.com/questions/8886683/read-stdin-for-user-input-when-a-file-is-already-redirected-to-stdinスクリプトを次のように修正しました。

while read -r ONE <&3; do
    read -r TWO <&3
    echo $ONE
    echo $TWO
    read -n 1 -p "Would you like to copy the above 2 lines to the new  file? [Y,n]" ans
        if [[ $ans == "Y" || $ans == "y" ]]; then
                printf $ONE >>file2.txt && printf $TWO >>file2.txt
        else
                echo "Resuming loop"
        fi
done 3<file1.txt

これにより、既定では、私が読み込んでいるファイルの行のペアを標準入力にコピーして別のファイルにコピーできます。ほとんど私が望んでいたものです。コピーした行のペアが同じ行で終わらないように、作成しているファイルに改行文字を挿入する方法を理解してください。追加の入力と説明を歓迎します。

答え1

次の行を変更してください。

printf $ONE >>file2.txt && printf $TWO >>file2.txt

到着

printf "$ONE\n" >>file2.txt && printf "$TWO\n" >>file2.txt

これにより、各 printf 文の出力が新しい行に配置されます。

答え2

使用幸せ(以前のPerl_6)

raku -ne 'm/blah | blob/ ?? put($_, "\n", get) !! next;'  

#OR

raku -e 'for lines() { m/blah | blob/ ?? put($_, "\n", get) !! next};' 

または

raku -e 'for lines.rotor(2) { .join("\n").put if m/blah | blob/ };'

#OR

raku -e 'for lines.batch(2) { .join("\n").put if m/blah | blob/ };'

必ずそうでしょうかbash?これはRakuで書かれた答えです。 Rakuのlinesルーチンは入力をゆっくり読み取るので非常に効率的です。最初の2つの答えは一致する行を返し、gets-and-は各一致の後の行を返します。

3番目の答えは、rotor一度に2行を分析できるように各ペアをまとめて配置します。 4番目の例rotorでは、「不完全/部分」グループ化が最後に削除されるため、戻り部分のbatchグループ化(と同じrotor(2, partial => True))を使用します。

入力例:

#searchterm blah
possible additional needed line 1
#searchterm blee
possible additional needed line 2
#searchterm blob
possible additional needed line 3
#searchterm bloh
possible additional needed line 4
#searchterm bluh
possible additional needed line etc

出力例(4つの例すべて):

#searchterm blah
possible additional needed line 1
#searchterm blob
possible additional needed line 3

https://raku.org

関連情報