Usunąć długi prefiks tylko z określonego pola we wszystkich wierszach pliku?
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
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.
Użyłbym AWK
do tego w następujący sposób, niech treść file.txt
bę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)
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ę.
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.
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.
Używając sed
:
sed -E 's/^([^ ]* )([^/]*\/)*/\1/' infile
A także to awk
za 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