2 つの引数日付の間の出力行には最初の引数の日付が含まれますが、2 番目の引数の日付は含まれません。

2 つの引数日付の間の出力行には最初の引数の日付が含まれますが、2 番目の引数の日付は含まれません。

この質問は、2つの日付(該当する日付を含むまたは除く)の間のテキストを見つける場合を除いて、以前に要求されたものです。最初の日付を選択して含め、2番目の日付を除外するように回答の1つを変更しました(考え/希望)。しかし、これを適用したいテキストファイルをどこに提供するのかわかりません。

set - date1 date2 "junk"  

from="$1"
till="$2"
file="$3"  

# Output lines between two parameter dates 
# INCLUDING the first parameter date but not the second

awk -v from=$from -v till=$till '
    ($2 >= from) && ($2 < till) { print $0 ; next }
    ($2 >= till) { exit }' "$file"

私は、このような解決策を見つけたので、これを改善し、スクリプト行に小さな変更を何度も書くのを防ぐための別の側面があることに気づきました。

現在の作業ソリューションは次のとおりです。

awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt

それでも、新しい日付ごとにこれを実行したいと思います。たとえば、Date_1_(date_1_を含む)からDate_2_(Date_2_を除く)までのテキストを選択し、Date_2_から3まで同じ方法でテキストを選択し、3〜4(最大1000)まで同じ方法で選択します。簡単に拡張できるソリューションはありますか?

入力テキストファイルの例(実際のファイルは最大1000で、txtファイルの下線の間にスペースはありませんが、イタリック体効果を避けるためのバックティックはありません):

' > _ 1_ fe fi fo fum >_ 2_ beep bap bop >_ 3_ ti fi at at

出力例:
テキストファイル 1 生成済み: >_ 1_ fe fi fo fum
テキストファイル 2 生成済み: >_ 2_ beep bap bop
テキストファイル 3 生成済み: >_ 3_ ti fi at at

答え1

この進化する質問の現在の状態を正しく理解している場合は、任意の数の行を持つファイルがあり、 to のように表示されたセクションに分かれており、_1_その_1000_セクションを別々のファイルに分割したいと思います。その場合は、csplit次のようにできます。

 csplit file.txt '/^_[0-9]\+_/' '{*}'

答え2

このawkプログラムは、単一のコマンドで最初に実行したいことを行います。

awk '/^date_1_/,/^date_2_/ { if (prev) print prev ; prev=$0 }' file.txt > file2.txt

これをテストしましたが、うまくいきます。次に、引数のペアで指定された一連の一般的な線の表示に対して操作を実行できるように、問題を拡張します。

2つのヘルパー関数を定義することで、そのための快適なワークフローを作成できます。

  • 入力をプロセスに置き換える awk プログラムの作成
  • もう1つはawkを実行して最初のヘルパーに引数を渡します。

パスワード:

fun1(){ while [ ! -z $1 ] && [ ! -z $2 ] ; do echo "
/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; shift; shift ; done }

fun2(){ awk -f <(fun1 $@); }

# Example data, example ranges, but could be any string:
seq 1 13 | sed -e 's/.*/_&_/' | fun2 _2 _4 _9 _11
_2_
_3_
_9_
_10_

問題バージョン3の解決策:

fun3(){ echo "/^$1/,/^$2/ {if (\$0~/^$1/) prev=\"\";
if (prev) print prev; prev=\$0 }"; }

fun4(){ ifile=$1; shift; while [ ! -z $1 ] && [ ! -z $2 ] ; do
        awk -f <(fun3 $1 $2) $ifile > $1.txt ; shift; done }

# Create example data file:
seq 1 13 | sed -e 's/.*/_&_/' > inputData.txt

fun4 inputData.txt _2 _5 _8 _12

ls _*
_2.txt  _5.txt  _8.txt

答え3

私はもっ​​と本を読んで、今私に合うものを一つにまとめました。

awk '/^date_1_/,/^date_2_/ {print}' file.txt > file2.txt
grep -v "date_2_" file2.txt > file2tmp.txt
mv file2tmp.txt file2.txt

ただし、まだステップ2と一時ファイルが必要です。

関連情報