Exemple:
a43
test1
abc
cvb
bnm
test2
kfo
J'ai besoin de toutes les lignes entre test1 et test2. Grep normal ne fonctionne pas dans ce cas. Avez-vous des propositions?
Imprimer depuis
test1
àtest2
(Lignes de déclenchement incluses)
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
Imprime les données entre
test1
àtest2
(Lignes de déclenchement exclues)
awk '/test1/{f=1;next} /test2/{f=0} f'
awk '/test2/{f=0} f; /test1/{f=1}'
abc
cvb
bnm
Vous pouvez utiliser sed
:
sed -n '/test1/,/test2/p' filename
Pour exclure les lignes contenant test1
et test2
, dire:
sed -n '/test1/,/test2/{/test1/b;/test2/b;p}' filename
Si vous ne pouvez utiliser que grep:
grep -A100000 test1 file.txt | grep -B100000 test2 > new.txt
grep -A
puis un nombre obtient les lignes après la chaîne correspondante et grep -B
obtient les lignes avant la chaîne correspondante. Le nombre, 100 000 dans ce cas, doit être assez grand pour inclure toutes les lignes avant et après.
Si vous ne souhaitez pas inclure test1 et test2, vous pouvez ensuite les supprimer en grep -v
, qui affiche tout sauf la ou les lignes correspondantes:
egrep -v "test1|test2" new.txt > newer.txt
ou tout en une ligne:
grep -A100000 test1 file.txt | grep -B100000 test2 | egrep -v "test1|test2" > new.txt
Oui, grep normal ne le fera pas. Mais grep avec -P
paramètre fera ce travail.
$ grep -ozP '(?s)test1\n\K.*?(?=\ntest2)' file
abc
cvb
bnm
\K
_ élimine les caractères précédemment correspondants de l’impression lors de la finale et l’anticipation positive (?=\ntest2)
affirme que la correspondance doit être suivie d'un \n
caractère de nouvelle ligne, puis test2
chaîne.
La réponse de PratPor ci-dessus:
cat test.txt | grep -A10 test1 | grep -B10 test2
c'est cool .. mais si vous ne connaissez pas la longueur du fichier:
cat test.txt | grep -A1000 test1 | grep -B1000 test2
Pas déterministe, mais pas trop mal. Quelqu'un a mieux (plus déterministe)?
Vous pouvez faire quelque chose comme ça aussi. Disons que vous ce fichier test.txt
avec contenu:
a43
test1
abc
cvb
bnm
test2
kfo
Tu peux faire
cat test.txt | grep -A10 test1 | grep -B10 test2
où -A<n>
est de vous obtenir n
lignes après votre correspondance dans le fichier et -B<n>
est de vous donner n
lignes avant le match. Vous devez juste vous assurer que n > number of expected lines between test1 and test2
. Ou vous pouvez le donner assez grand pour atteindre EOF.
Résultat:
test1
abc
cvb
bnm
test2
Le script suivant termine ce processus. Plus de détails dans cet article similaire 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 $*