Supprimer le préfixe long uniquement d'un champ spécifique dans toutes les lignes d'un fichier?

Nov 21 2020

J'ai un fichier contenant les lignes suivantes (3 champs délimités par un espace):

component1 /dev/user/test 12344
component2 master abcefa123
component3 trunk 72812
component4 /branch/user/integration bc89fa
component5 trunk 989091 
component6 integration/test bc7829ac
component7 /branch/dev/user/various eded34512

Je dois manipuler le champ 2 pour couper son long préfixe (comme vous le faites dans bash avec $ {string ## *}) et obtenir le résultat suivant:

component1 test 12344
component2 master abcefa123
component3 trunk 72812
component4 integration bc89fa
component5 trunk 989091 
component6 test bc7829ac
component7 various eded34512

Je ne sais pas comment faire.

Réponses

2 RavinderSingh13 Nov 21 2020 at 12:27

1ère solution: pourriez-vous s'il vous plaît essayer de suivre, écrit et testé avec les exemples présentés dans GNUawk.

awk '{num=split($2,arr,"/");$2=arr[num]} 1' Input_file

2ème solution: OU avec les échantillons affichés, essayez uniquement de définir les séparateurs de champ comme espace ou/.

awk -F'[ /]' '{print $1,$(NF-1),$NF}' Input_file

3ème solution (en utilisant sed): En utilisantsed, vous pouvez essayer comme:

sed 's/\([^ ]*\).*\/\(.*\)/\1 \2/' Input_file

Explication (1ère solution): Ajout d'une explication détaillée pour ci-dessus.

awk '                   ##Starting awk program from here.
{
  num=split($2,arr,"/") ##Splitting 2nd field into array arr with / as field separator.
                        ##num is number of total elements of array arr.
  $2=arr[num]           ##Assigning last element of arr with index of num into 2nd field.
}
1                       ##Mentioning 1 will print the current line.
' Input_file            ##mentioning Input_file name here.
2 Daweo Nov 21 2020 at 12:57

J'utiliserais AWKpour cette manière suivante, laissez le contenu de file.txtêtre:

component1 /dev/user/test 12344
component2 master abcefa123
component3 trunk 72812
component4 /branch/user/integration bc89fa
component5 trunk 989091 
component6 integration/test bc7829ac
component7 /branch/dev/user/various eded34512

puis

awk '{sub(/^.*\//, "", $2);print}' file.txt

les sorties:

component1 test 12344
component2 master abcefa123
component3 trunk 72812
component4 integration bc89fa
component5 trunk 989091 
component6 test bc7829ac
component7 various eded34512

Explication Je remplace simplement tout du début au dernier /(qui doit être échappé par conséquent \) dans la colonne d'intérêt par une chaîne vide, puis printelle.

(testé dans GNU Awk 5.0.1)

Luuk Nov 21 2020 at 12:27

Une solution avec awk:

awk '{ split($2,s,"/"); $2=s[length(s)]; print }' inputfile

Le split($2,s,"/")divisera la deuxième variable en un tableau

$2=s[length(s)]; affectera la deuxième variable avec la dernière valeur du tableau

print imprimera la ligne complète.

RamanSailopal Nov 21 2020 at 12:27
awk '{ split($2,map,"/");$2=map[length(map)] }1' file

En utilisant awk. divisez le deuxième champ délimité par des espaces en un tableau appelé map en utilisant / comme délimiteur. Remplacez $ 2 par le dernier élément du tableau de la carte. Imprimez les lignes avec un raccourci 1.

RamanSailopal Nov 21 2020 at 12:43

Utilisation de sed:

sed -rn 's/(^.*)([[:space:]])(.*\/)?(.*)([[:space:]])(.*$)/\1 \4 \6/p' file

Divisez chaque ligne en sections basées sur des expressions régulières et remplacez la ligne par les sections pertinentes, en imprimant le résultat.

αғsнιη Nov 21 2020 at 13:03

Utilisation sed:

sed -E 's/^([^ ]* )([^/]*\/)*/\1/' infile
CarlosPascual Nov 22 2020 at 10:08

Et aussi cela en awkutilisant la boucle while:

awk '{while ( n=split($2,a,/\//) ) {$2=a[n];print;next}}' file
component1 test 12344
component2 master abcefa123
component3 trunk 72812
component4 integration bc89fa
component5 trunk 989091
component6 test bc7829ac
component7 various eded34512