regex - شرح - باش، غريب بين سطرين مع سلسلة محددة




there's a specific term for the patterns that grep lets you use (6)

مثال:

a43
test1
abc
cvb
bnm
test2
kfo

أحتاج إلى جميع الخطوط بين test1 و test2. عادي لا يعمل غريب في هذه الحالة. هل لديك أي اقتراحات؟

https://code.i-harness.com


إذا كان يمكنك فقط استخدام غريب:

grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt

grep -A ثم عدد يحصل على خطوط بعد سلسلة مطابقة، و grep -B يحصل على خطوط قبل سلسلة مطابقة. الرقم، 100000 في هذه الحالة، يجب أن تكون كبيرة بما فيه الكفاية لتشمل جميع الخطوط قبل وبعد.

إذا كنت لا تريد تضمين test1 و test2، فيمكنك إزالتها بعد ذلك بواسطة grep -v ، الذي يطبع كل شيء ما عدا السطر (الخطوط) المطابق:

egrep -v "test1|test2" new.txt > newer.txt

أو كل شيء في سطر واحد:

grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt 

لها بعض awk هذه سوف تطبع من test1 إلى test2

awk '/test1/{f=1} /test2/{f=0;print} f'
awk '/test1/{f=1} f; /test2/{f=0}' 
awk '/test1/,/test2/'

test1
abc
cvb
bnm
test2

هذه البيانات يطبع بين test1 إلى test2

awk '/test1/{f=1;next} /test2/{f=0} f' 
awk '/test2/{f=0} f; /test1/{f=1}' 

abc
cvb
bnm

awk '/test1/,/test2/' filename.txt > outputFile.txt

نعم، سوف غريب العادي لا تفعل هذا. ولكن غريب مع المعلمة -P سوف تفعل هذه المهمة.

$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file
abc
cvb
bnm

\K يتجاهل الأحرف المتطابقة سابقا من الطباعة في نهاية المطاف و لوكهيد إيجابية (?=\ntest2) يؤكد أن المباراة يجب أن يتبعها حرف \n جديد ثم سلسلة test2 .


الجواب من قبل براتبور أعلاه:

cat test.txt | grep -A10 test1 | grep -B10 test2

هو بارد .. ولكن إذا كنت لا تعرف طول الملف:

cat test.txt | grep -A1000 test1 | grep -B1000 test2

ليس حتمية، ولكن ليس سيئا للغاية. أي شخص أفضل (أكثر حتمية)؟


السيناريو التالي يلتف هذه العملية. مزيد من التفاصيل في هذا مماثل ستاكوفيرفلو وظيفة

get_text.sh

function show_help()
{
  HELP=$(doMain $0 HELP)
  echo "$HELP"
  exit;
}

function doMain()
{
  if [ "$1" == "help" ]
  then
    show_help
  fi
  if [ -z "$1" ]
  then
    show_help
  fi
  if [ -z "$2" ]
  then
    show_help
  fi

  FILENAME=$1
  if [ ! -f $FILENAME ]; then
      echo "File not found: $FILENAME"
      exit;
  fi

  if [ -z "$3" ]
  then
    START_TAG=$2_START
    END_TAG=$2_END
  else
    START_TAG=$2
    END_TAG=$3
  fi

  CMD="cat $FILENAME | awk '/$START_TAG/{f=1;next} /$END_TAG/{f=0} f'"
  eval $CMD
}

function help_txt()
{
HELP_START
  get_text.sh: extracts lines in a file between two tags

  usage: FILENAME {TAG_PREFIX|START_TAG} {END_TAG}

  examples:
    get_text.sh 1.txt AA     => extracts lines in file 1.txt between AA_START and AA_END
    get_text.sh 1.txt AA BB  => extracts lines in file 1.txt between AA and BB
HELP_END
}

doMain $*




grep