Langes Präfix nur aus einem bestimmten Feld in allen Zeilen einer Datei entfernen?
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
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.
Ich würde AWK
für diesen folgenden Weg verwenden, Inhalt von file.txt
sein 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 print
es.
(getestet in GNU Awk 5.0.1)
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.
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.
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.
Verwenden von sed
:
sed -E 's/^([^ ]* )([^/]*\/)*/\1/' infile
Und auch dies awk
mit 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