Usuń ostatni znak z linii


54

Chcę usunąć ostatni znak z linii:

[root@ozzesh ~]#df -h | awk  '{ print $5 }'
Use%
22%
1%
1%
59%
51%
63%
5%

Spodziewany wynik:

Use
22
1
1
59
51
63
5

2
Czy to zawsze %znak?
Bernhard

Odpowiedzi:


83
sed 's/.$//'

Aby usunąć ostatni znak.

Ale w tym konkretnym przypadku możesz również:

df -P | awk 'NR > 1 {print $5+0}'

Za pomocą wyrażenia arytmetycznego ( $5+0) zmuszamy awkdo interpretacji piątego pola jako liczby, a wszystko po liczbie zostanie zignorowane.

Zauważ, że GNU df(twoje -hjest już rozszerzeniem GNU, choć nie jest tutaj potrzebne) może również zostać poinformowane, aby wyświetlało tylko procent wykorzystania dysku:

df --output=pcent | tail -n +2 | tr -cd '0-9\n'

(tail pomija nagłówki, a tr usuwa wszystko oprócz cyfr i ograniczników linii).

W systemie Linux zobacz także:

findmnt -no USE%

9
{print +$5}będzie również działać ...
jasonwryan

1
@ jasonwryan, niestety, istnieje wiele awkimplementacji, w których to nie działa , w których +operator jednoargumentowy jest po prostu ignorowany i nie wymusza konwersji ciągów na wartości liczbowe.
Stéphane Chazelas,

20

Dzięki sedjest to dość łatwe:

$ cat file
Use%
22%
1%
1%
59%
51%
63%
5%
$ sed 's/.$//' file
Use
22
1
1
59
51
63
5

Składnia jest następująca s(ubstitute)/search/replacestring/. .Oznacza dowolny znak, a $na koniec linii. Usunie więc .$tylko ostatnią postać.

W takim przypadku pełne polecenie wyglądałoby następująco:

df -h | awk '{ print $5}' | sed 's/.$//'

2
Rura do sedjest zbędna: można to zrobić w awk:df -h | awk '{gsub(/%/,""); print $5}'
jasonwryan

@jasonwryan W takim razie bardziej podoba mi się rozwiązanie Stephane'a.
Bernhard

15

Mam dwa rozwiązania:

  1. kroić: echo "somestring1" | rev | cut -c 2- | rev

    Tutaj odwróć ciąg i odetnij ciąg od 2. znaku i ponownie odwróć.

  2. sed: echo "somestring1" | sed 's/.$//'

    W tym miejscu wyszukasz wyrażenie regularne, .$co oznacza dowolne znaki, po których następuje ostatni znak i zastąpisz go znakiem null //(między dwoma ukośnikami)


7

W awk możesz zrobić jedną z nich

awk '{sub(/%$/,"",$5); print $5}'
awk '{print substr($5, 1, length($5)-1)}'

2

inne podejście:

mapfile -t list < <(df -h)
printf '%s\n' "${list[@]%?}"

Zmień go w funkcję:

remove_last() {
  local char=${1:-?}; shift
  mapfile -t list < <("$@")
  printf '%s\n' "${list[@]%$char}"
}

Następnie nazwij to tak:

remove_last '%' df -h

mapfile jest funkcją bash4.

Problem polega na tym, że musisz podać postać do usunięcia; jeśli chcesz, aby była to po prostu ostatnia postać , musisz zdać '?'lub ''. wymagane cytaty.



1

Spróbuj tego:

df -h | awk  '{ print $5 }' | sed "s/%//"

Normalne użycie to: (tj.)

VALUE=987654321
echo X123456789X | sed "s/123456789/${VALUE}/"

Odpowiedź powinna wynosić: X987654321X


1
df -h | awk 'NR > 1{ print $5 }' | cut -d "%" -f1

Ta odpowiedź może być bardziej pomocna dla osób spoza PO, jeśli możesz podać trochę wyjaśnienia na temat tego, jak to działa i być może dlaczego może to być lepsze niż alternatywy
Fox

Witamy w Unix Stackexchange! Możesz wybrać się na wycieczkę, aby poznać działanie tej witryny. Przy udzielaniu odpowiedzi lepiej wyjaśnić, DLACZEGO twoja odpowiedź jest tą, której chce czytelnik. Oznacza to, że najlepiej jest wyjaśnić, jak to działa. Jeśli spojrzysz powyżej, zobaczysz, że wszystkie wysoko głosowane odpowiedzi wyjaśniają kod.
Stephen Rauch

Wybitny za użycie cut -d '%' -f1którego jest prawidłową odpowiedzią, aby uzyskać wszystko w linii do pierwszego „%”.
Titou,

Ponadto uważam, że tylko szkodliwe / błędne odpowiedzi powinny zostać ocenione poniżej 0
Titou

0
sed -ie '$d' filename

here -i is to write changes
      e means expression
      $ means last line
      d means delete

Note:Without -e option $ wont work

Opcjonalnie : Aby usunąć pierwszy i ostatni wiersz, użyj sed -ie '1d;$d'nazwy pliku


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.