Dans le fichier suivant:
Lorem ipsum dolor assis amet, élit adipiscing consectetuer. Ut eu metus id lectus vestibulum ultrices. Maecenas rhoncus.
Je veux tout supprimer avant consectetuer
et tout après elit
.
Ma sortie souhaitée:
consectetuer adipiscing elit.
Comment puis-je faire ceci?
J'utiliserais sed
sed 's/^.*\(consectetuer.*elit\).*$/\1/' file
Décodage de la syntaxe sed s/find/replace /:
s/^.*
- substitut commençant au début de la ligne (^
) suivi de tout (.*
) Jusqu'à...\(
- démarre un bloc nomméconsectetuer.*elit\.
- correspond au premier mot, tout (.*
) jusqu'au dernier mot (dans ce cas, y compris le point de fin (d'échappement)) que vous souhaitez faire correspondre\)
- termine le bloc nommé.*
) jusqu'à la fin de la ligne ($
)/
- termine la section de recherche de substitution\1
- remplacez par le bloc de nom entre le \(
et le \)
au dessus de/
- terminer le remplacementSi chaque ligne contient à la fois un motif de début et un motif de fin, la façon la plus simple de le faire est d'utiliser grep
. Au lieu de supprimer le début et la fin de chaque ligne, vous pouvez simplement afficher le contenu entre les deux modèles. Le -o
option dans GNU grep
affiche uniquement les correspondances:
grep -o 'consectetuer.*elit' file
Remarque: comme mentionné, cela ne fonctionne que si chaque ligne du fichier peut être analysée de cette façon. Là encore, c'est 80% de tous les cas d'utilisation typiques.
Deux pour les boucles dans AWK:
$ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n" }' file.txt
consectetuer adipiscing elit.
Gsub d'AWK:
$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.
Une façon Perl. C'est essentiellement la même chose que la réponse sed
de MikeV:
Perl -pe 's/.*(consectetuer.*elit).*./$1/' file
Le -p
signifie "imprimer chaque ligne après avoir appliqué le script donné avec -e
". Le s/foo/bar/
est l'opérateur de substitution; il remplacera foo
par bar
. Les parenthèses capturent un motif et utilisons-le dans le remplacement. Le premier motif capturé est $1
, la deuxième $2
etc.
Ainsi, la commande correspondra à tout jusqu'à consectetuer
(.*consectetuer
), puis tout jusqu'à elit
(.*elit
) puis tout le reste jusqu'à la fin de la ligne (.*
) et le remplacera par le motif capturé.
Je ne sais pas pourquoi ce titre de question a été modifié " du fichier " en " d'une ligne "alors que l'OP n'exclut pas la possibilité sur plusieurs lignes même si l'exemple semble être une seule ligne. Quoi qu'il en soit, il pourrait être utile de fournir ici une solution à plusieurs lignes.
Cela fonctionne pour les lignes croisées:
from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
Exemples:
[xiaobai@xiaobai tmp]$ cat file
1
abc consectetuer lsl
home
def elit dd
2 consectetuer ABC elit
[xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2"
consectetuer lsl
home
def elit
[xiaobai@xiaobai tmp]$
référence: Expansion des paramètres du shell