Ejemplo:
a43 test1 abc cvb bnm test2 kfo
Necesito todas las líneas entre test1 y test2. Grep normal no funciona en este caso. ¿Tienes alguna proposición?
Ella es un poco awk
Estas se imprimirán de test1
a 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
Estos imprimen datos entre test1
a test2
awk '/test1/{f=1;next} /test2/{f=0} f' awk '/test2/{f=0} f; /test1/{f=1}'
abc cvb bnm
Puedes usar sed
:
sed -n '/test1/,/test2/p' filename
Para excluir las líneas que contienen test1
y test2
, diga:
sed -n '/test1/,/test2/{/test1/b;/test2/b;p}' filename
Si solo puedes usar grep:
grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt
grep -A
y luego un número obtiene las líneas después de la cadena correspondiente, y grep -B
obtiene las líneas antes de la cadena correspondiente. El número, 100000 en este caso, debe ser lo suficientemente grande como para incluir todas las líneas antes y después.
Si no desea incluir test1 y test2, puede eliminarlos luego mediante grep -v
, que imprime todo excepto la (s) línea (s) correspondiente (s):
egrep -v "test1|test2" new.txt > newer.txt
o todo en una línea:
grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt
Sí, grep normal no hará esto. Pero grep con el parámetro -P
hará este trabajo.
$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file abc cvb bnm
\K
descarta que los caracteres previamente coincidentes se (?=\ntest2)
en la final y el aspecto positivo hacia (?=\ntest2)
afirma que la coincidencia debe ir seguida de un \n
carácter de nueva línea y luego una cadena de test2
.
La respuesta de PratPor arriba:
cat test.txt | grep -A10 test1 | grep -B10 test2
es genial … pero si no sabes la longitud del archivo:
cat test.txt | grep -A1000 test1 | grep -B1000 test2
No es determinista, pero no está mal. ¿Alguien tiene mejor (más determinista)?
La siguiente secuencia de comandos finaliza este proceso. Más detalles en esta publicación similar de StackOverflow
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 $*
Usted puede hacer algo como esto también. Permite decir que este archivo test.txt
con contenido:
a43 test1 abc cvb bnm test2 kfo
Tu puedes hacer
cat test.txt | grep -A10 test1 | grep -B10 test2
donde -A
es para obtener n
líneas después de su coincidencia en el archivo y -B
es para darle n
líneas antes de la coincidencia. Solo tiene que asegurarse de que n > number of expected lines between test1 and test2
. O puede darlelo lo suficientemente grande como para llegar a EOF.
Resultado:
test1 abc cvb bnm test2