Extraction d'une partie des lignes avec un motif spécifique en utilisant awk, sed

18

J'ai une question concernant les opérateurs awk / sed. J'ai un gros fichier qui a répété l'ensemble des lignes suivantes

Expression loweWallrhoPhi :  sum=-6.97168e-09
Expression leftWallrhoPhi :  sum=6.97168e-09
Expression lowerWallPhi :  sum=-5.12623e-12
Expression leftWallPhi :  sum=5.12623e-12
Expression loweWallrhoUSf :  sum=-6.936e-09
Expression leftWallrhoUSf :  sum=6.97169e-09
Expression lowerWallUSf :  sum=-5.1e-12
Expression leftWallUSf :  sum=5.12624e-12

Je veux extraire la valeur après somme dans chaque cas dans un fichier séparé. Est-il possible de le faire d'un seul coup?

Pimpalgaonkar Hrushikesh
la source

Réponses:

26

Avec la commande grep:

grep -oP 'sum=\K.*' inpufile > outputfile

grep avec -P(perl-regexp) prend en charge les paramètres \K, qui permettent d'ignorer les caractères précédemment mis en correspondance.

Avec la commande awk:

awk -F"=" '{print $NF}' inputfile > outputfile

Awk NFvous donne le nombre total de champs dans un enregistrement / ligne. Ainsi, la dernière valeur de cela est le dernier numéro de champ dans un enregistrement / ligne.

Avec la commande sed:

sed 's/^.*sum=//' inpufile > outputfile

^.*=sumremplacer tous les caractères ( .*) entre le début de la ligne ( ^) et les derniers caractères ( sum=) par un caractère d'espacement.

Résultat:

-6.97168e-09
6.97168e-09
-5.12623e-12
5.12623e-12
-6.936e-09
6.97169e-09
-5.1e-12
5.12624e-12

Si vous souhaitez enregistrer chaque valeur dans un fichier séparé, utilisez les commandes ci-dessus dans une boucle while:

while read line; do
    echo "$line" | grep -oP 'sum=\K.*'     > $(echo "$line" |awk '{print $2}');
   #echo "$line" | awk -F"=" '{print $NF}' > $(echo "$line" |awk '{print $2}');
   #echo "#line" | sed 's/^.*sum=//'       > $(echo "$line" |awk '{print $2}');
done < file
αғsнιη
la source
Cela inclut le sum=et ce n'est pas la même chose que la valeur aprèssum=
Anthon
OP veut la valeur après somme, aussi cette description awk de NF est horrible.
1
Pour compléter cette très bonne réponse, vous pouvez également utiliser cut: cut -d'=' -f2 file.
fedorqui
Ceci est une très bonne réponse. Je l'ai aimé. Je vous remercie.
Jaffer Wilson
6

Si je comprends bien la question, vous souhaitez obtenir uniquement des valeurs après =, et stocker ces valeurs dans des fichiers séparés, en fonction du deuxième champ (?). Si j'ai raison, essayez quelque chose comme ceci:

$ awk -F'[ =]' '{print $6>"file_"$2".txt"}' file

Le résultat:

$ ls -1
  file_leftWallPhi.txt
  file_leftWallUSf.txt
  file_leftWallrhoPhi.txt
  file_leftWallrhoUSf.txt
  file_loweWallrhoPhi.txt
  file_loweWallrhoUSf.txt
  file_lowerWallPhi.txt
  file_lowerWallUSf.txt

$ cat  file_leftWallPhi.txt
  5.12623e-12
jimmij
la source
@KasiyA Je ne peux pas reproduire votre problème avec GNU awk 4.0.2. La commande de ma réponse fonctionne également avec -coption (mode de compatibilité avec UNIX traditionnel awkoù les extensions GNU sont désactivées). Veuillez vous assurer que vous avez mis à jour le fichier d'entrée car la question d'origine a été modifiée et les lignes vides supprimées.
jimmij
1

Vous pouvez le faire en sed

sed -E 's/^.* (\S+)\s*:.*=(\S+)/echo "\2" > "\1".txt/' file | bash

Le script découvre deux morceaux en ligne:

  1. entre les espaces et :et devrait contenir certains (plus de 0) symboles non spatiaux;
  2. quelques (plus de 0) symboles non spatiaux après =;

et le format de sa commande en cours d'exécution qui a transféré à travers le tuyau vers bash

Costas
la source
Une réponse beaucoup plus polyvalente.
duanev