Jak usunąć pierwsze znaki X z ciągu za pomocą seda?

126

Piszę skrypt powłoki dla wbudowanego Linuksa w małym przemysłowym pudełku. Mam zmienną zawierającą tekst pid: 1234i chcę usunąć pierwsze X znaków z linii, więc pozostaje tylko 1234. Mam więcej zmiennych, które muszę „wyczyścić”, więc muszę wyciąć X pierwszych znaków iz ${string:5}jakiegoś powodu nie działa w moim systemie.

Wydaje się, że jedyne, co ma to pudełko, to sed.

Próbuję, aby zadziałało:

result=$(echo "$pid" | sed 's/^.\{4\}//g')

Jakieś pomysły?

Kokesh
źródło
10
Jeśli ${string:5}nie działa, nie używasz Bash ani innej powłoki obsługującej tę składnię. Jakiej powłoki i wersji używasz? Jak wygląda twój shebang? Domyślam się, że używasz sh(np. dash) Lub prawdopodobnie zsh.
Wstrzymano do odwołania.

Odpowiedzi:

0

To też wykona zadanie:

echo "$pid"|awk '{print $2}'
Arnaud F.
źródło
27
To pytanie jest pierwszym trafieniem dotyczącym „pomiń pierwszych N znaków w ciągu”. Nie odpowiedziałeś na pytanie.
jww
To wydaje się nie działać, a jeśli tak, czy możesz wyjaśnić, jak to zrobić
Alexander Mills,
To działa w moim systemie. Może występować problem z separatorem pól, spróbuj awk -F": " '{print $2}'. Jednak nie jest to moje ulubione rozwiązanie.
mzuther
197

Powinno działać:

var="pid: 1234"
var=${var:5}

Czy na pewno bashpowłoka wykonuje Twój skrypt?

Nawet zgodny z POSIX

var=${var#?????}

byłoby lepsze niż użycie procesu zewnętrznego, chociaż wymaga to sztywnego zakodowania 5 w postaci wzorca o stałej długości.

Chepner
źródło
1
Możesz również określić długość za pomocą drugiego parametru: ${var:5:2}rozpocznie się o 1i wróci 12.
Max Candocia,
107

Oto zwięzła metoda wycinania pierwszych znaków X za pomocą cut(1). Ten przykład usuwa pierwsze 4 znaki, wycinając podciąg zaczynający się od piątego znaku.

echo "$pid" | cut -c 5-
Randy the Dev
źródło
2
To najprostsze rozwiązanie!
Brandon
2
Technicznie rzecz biorąc, OP poprosił o seda, ale wydaje mi się, że jest to najlepsze rozwiązanie dla „Jak mogę usunąć pierwsze znaki X z łańcucha [w terminalu / bash]” W połączeniu z git jest przyjemne:git log --pretty=oneline | cut -c 42- | head
marksiemers
1
+1 Proste i pomocne rozwiązanie. Kiedy miałem adres URL jako http: // <example.com> i wycinałem protokół „http: //”, muszę powiedzieć, że jest to 8 znaków zamiast 7. Nie wiem , ale tak to u mnie zadziałało.
Santosh Kumar Arjunan
1
Santosh Kumar Arjunan: to dlatego, że przykład "echo" $ pid "| cut -c 4-" w rzeczywistości nie wycina pierwszych 4 znaków, ale wyodrębnia podciąg zaczynający się od czwartego znaku. Dlatego faktycznie wycina pierwsze 3 znaki. Tak więc, jeśli chcesz wyciąć 7 pierwszych znaków, chcesz wyodrębnić wszystko z ósmego znaku, a tym samym faktycznie wykonać „cut -c 8-”
al-ash
1
@DeanHiller cut -c ${LEN}-. Nawiasy klamrowe służą do konkatenacji ciągu z prawidłowymi znakami zmiennych, aby odróżnić, co jest zmienną, a co nią nie jest. Jeśli chcesz uzyskać więcej informacji na ten temat, poszukaj „konkatenacji łańcuchów zmiennych bash”, aby uzyskać więcej informacji o tym, dlaczego / jak to działa.
JustCarty
46

Użyj -ropcji ("użyj rozszerzonych wyrażeń regularnych w skrypcie") sedaby użyć {n}składni:

$ echo 'pid: 1234'| sed -r 's/^.{5}//'
1234
Mark Longair
źródło
1
jak by to było w przypadku, gdybym chciał usunąć ostatnie X znaków z ciągu?
Kokesh
5
@Kokesh: sed -r 's/.{5}$//'zamiast tego możesz usunąć ostatnie 5 znaków
Mark Longair
7
Możesz to zrobić bez -r( -Ew OS X, IIRC), jeśli unikniesz nawiasów klamrowych (nie wiem, czy to działa w OS X).
Wstrzymano do odwołania.
2
@Dennis: Właśnie sprawdziłem - wyjście z nawiasów klamrowych (i pozostawienie wyłączenia -r/ -E) działa w systemie OS X.
Gordon Davisson
15

Wytnij pierwsze dwa znaki z ciągu:

$ string="1234567890"; echo "${string:2}"
34567890
dtp70
źródło
@ dtp70 Wielkie dzięki za ogólną odpowiedź, zadziałało świetnie!
wolfram77
10

przepuść go awk '{print substr($0,42)}'tam, gdzie 42 jest o jeden więcej niż liczba znaków do usunięcia. Na przykład:

$ echo abcde| awk '{print substr($0,2)}'
bcde
$
Ben
źródło
8

Jest szansa, że ​​ty cutteż. W takim razie:

[me@home]$ echo "pid: 1234" | cut -d" " -f2
1234
Shawn Chin
źródło
1
Problem cutpolega na tym, że nie radzi sobie rozsądnie z sekwencjami białych znaków, a użycie tr -s ' 'do „ściśnięcia” spacji sprawia, że ​​zachowuje się lepiej.
Thor,
1
To nie jest przeznaczone do śpiewania i tańca; jest prosty i robi to, co mówi na puszce i jest szeroko dostępny. Powinien działać dobrze w przypadku wspomnianych wymagań iz pewnością jest bardziej wytrzymały niż wycinanie stałych znaków z określonych pozycji.
Shawn Chin
5

Cóż, nie było tu rozwiązania z sed, awk, cuti stosując bashskładnię. Chcę tylko dorzucić inny wariant zgodny z POSIX:

$ echo "pid: 1234" | tail -c +6
1234

-cmówi tailowi, od którego offsetu bajtu ma się rozpocząć, licząc od końca danych wejściowych, ale jeśli liczba zaczyna się od +znaku, to od początku danych wejściowych do końca.

Mecki
źródło
4

Inny sposób, używając cutzamiast sed.

result=`echo $pid | cut -c 5-`
Evgeny
źródło
Chce usunąć pierwsze 4 znaki. To daje pierwsze 4 znaki.
MM.
2

Znalazłem odpowiedź w czystym sedzie dostarczonym przez to pytanie (wprawdzie opublikowane po opublikowaniu tego pytania). Robi dokładnie to, o co prosiłeś, wyłącznie w sed:

result=\`echo "$pid" | sed '/./ { s/pid:\ //g; }'\``

Kropka w sed '/./) to wszystko, co chcesz dopasować. Twoje pytanie jest dokładnie tym, co próbowałem, z wyjątkiem tego, że w moim przypadku chciałem dopasować konkretną linię w pliku, a następnie odkomentować ją. W moim przypadku było to:

# Uncomment a line (edit the file in-place):
sed -i '/#\ COMMENTED_LINE_TO_MATCH/ { s/#\ //g; }' /path/to/target/file

-iPo sedto, aby edytować plik w miejscu (usunąć ten przełącznik, jeśli chcesz przetestować wyraz pasujący przed edycję pliku).

(Opublikowałem to, ponieważ chciałem to zrobić całkowicie z sedem, ponieważ zadawano to pytanie i żadna z poprzednich odpowiedzi nie rozwiązała tego problemu).

treehead
źródło
1

Zamiast usuwać n znaków od początku, możesz po prostu bezpośrednio wyodrębnić cyfry. Tak jak tak ...

$ echo "pid: 1234" | grep -Po "\d+"

Może to być solidniejsze rozwiązanie i wydaje się bardziej intuicyjne.

user1751825
źródło