Usunąć długi prefiks tylko z określonego pola we wszystkich wierszach pliku?

Nov 21 2020

Mam plik zawierający następujące wiersze (3 pola oddzielone spacjami):

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

Muszę manipulować polem 2, aby wyciąć jego długi prefiks (tak samo jak w bash z $ {string ## *}) i uzyskać następujący wynik:

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

Nie mam pojęcia, jak to zrobić.

Odpowiedzi

2 RavinderSingh13 Nov 21 2020 at 12:27

Pierwsze rozwiązanie: czy mógłbyś spróbować śledzić, napisać i przetestować pokazane próbki w GNUawk.

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

Drugie rozwiązanie: LUB z pokazanymi próbkami spróbuj ustawić separatory pól jako spacje lub/.

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

Trzecie rozwiązanie (używanie sed): Używającsed, możesz spróbować:

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

Wyjaśnienie (pierwsze rozwiązanie): dodanie szczegółowego wyjaśnienia powyższego.

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

Użyłbym AWKdo tego w następujący sposób, niech treść file.txtbędzie:

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

następnie

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

wyjścia:

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

Wyjaśnienie Po prostu zastępuję wszystko, od początku do końca /(co musi być więc zmienione \) w kolumnie zainteresowania pustym ciągiem, a następnie print.

(przetestowano w GNU Awk 5.0.1)

Luuk Nov 21 2020 at 12:27

Rozwiązanie z awk:

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

split($2,s,"/")Podzieli drugą varable do tablicy

$2=s[length(s)]; przypisze drugiej zmiennej ostatnią wartość tablicy

print wypisze całą linię.

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

Korzystanie z awk. podzielić drugie pole rozdzielane spacjami na tablicę o nazwie map, używając / jako separatora. Zastąp $ 2 ostatnim elementem tablicy map. Wydrukuj wiersze ze skrótem 1.

RamanSailopal Nov 21 2020 at 12:43

Korzystanie sed:

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

Podziel każdy wiersz na sekcje na podstawie wyrażeń regularnych i zamień wiersz na odpowiednie sekcje, drukując wynik.

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

Używając sed:

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

A także to awkza pomocą pętli 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