Langes Präfix nur aus einem bestimmten Feld in allen Zeilen einer Datei entfernen?

Nov 21 2020

Ich habe eine Datei mit den folgenden Zeilen (3 durch Leerzeichen getrennte Felder):

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

Ich muss das Feld 2 manipulieren, um sein langes Präfix zu schneiden (genau wie in Bash mit $ {string ## *}) und um das folgende Ergebnis zu erhalten:

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

Ich habe keine Ahnung, wie es geht.

Antworten

2 RavinderSingh13 Nov 21 2020 at 12:27

1. Lösung: Könnten Sie bitte versuchen, mit den in GNU gezeigten Beispielen zu folgen, zu schreiben und zu testenawk.

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

2. Lösung: ODER versuchen Sie bei gezeigten Beispielen nur, Feldtrennzeichen als Leerzeichen oder festzulegen/.

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

3. Lösung (mit sed): Mitsed, könnten Sie versuchen, wie:

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

Erklärung (1. Lösung): Hinzufügen einer detaillierten Erklärung für oben.

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

Ich würde AWKfür diesen folgenden Weg verwenden, Inhalt von file.txtsein lassen:

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

dann

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

Ausgänge:

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

Erläuterung Ich ersetze einfach alles von Anfang bis Ende /(was daher maskiert werden muss \) in der interessierenden Spalte durch eine leere Zeichenfolge, dann printes.

(getestet in GNU Awk 5.0.1)

Luuk Nov 21 2020 at 12:27

Eine Lösung mit awk:

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

Das split($2,s,"/")teilt die zweite Variable in ein Array auf

$2=s[length(s)]; weist die zweite Variable mit dem letzten Wert des Arrays zu

print druckt die vollständige Zeile.

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

Mit awk. Teilen Sie das zweite durch Leerzeichen getrennte Feld in ein Array namens map auf, wobei Sie / als Begrenzer verwenden. Ersetzen Sie $ 2 durch das letzte Element des Kartenarrays. Drucken Sie die Zeilen mit der Kurzschrift 1.

RamanSailopal Nov 21 2020 at 12:43

Mit sed:

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

Teilen Sie jede Zeile basierend auf regulären Ausdrücken in Abschnitte auf und ersetzen Sie die entsprechenden Abschnitte durch die Zeile, indem Sie das Ergebnis drucken.

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

Verwenden von sed:

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

Und auch dies awkmit der Schleife 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