Wyodrębnij część jednego wiersza z pliku za pomocą sed


18

Chcę odczytać jedną część jednego wiersza z pliku. Na przykład:

POP3_SERVER_NAME = host lokalny

Chcę tylko wrócić localhost, używając sed.

Ten tekst jest w trzeciej linii. Robię to, aby wyodrębnić wiersz:

sed -n '3p' installation.sh

Jak wyodrębnić tylko localhostczęść?

Odpowiedzi:


26

awk może być lepszym narzędziem tutaj.

$ cat test.dat
LINE 1
LINE 2
POP3_SERVER_NAME = localhost

Wyszukaj wiersze zawierające „POP3_SERVER_NAME”; wydrukuj ostatnie pole. Nie zależy to od tego, że POP3_SERVER_NAME zawsze znajduje się na linii 3, co prawdopodobnie jest dobrą rzeczą.

$ awk '/POP3_SERVER_NAME/{print $NF}' test.dat
localhost

W zależności od aplikacji może być konieczne zaostrzenie wyrażenia regularnego. Na przykład możesz dopasować tylko tę linię, która zaczyna się od POP3_SERVER_NAME.

$ awk '/^POP3_SERVER_NAME/{print $NF}' test.dat
localhost

Korzystanie z sed jest nieco mniej intuicyjne. (Dzięki, zdaję sobie sprawę z ironii.) Zaadresuj wiersz zawierający POP3_SERVER_NAME w dowolnym miejscu. Zastąp pusty ciąg dla całego tekstu od początku wiersza do opcjonalnej spacji po „=”. Następnie wydrukuj.

sed -n -e '/POP3_SERVER_NAME/ s/.*\= *//p' test.dat

2
awkKomenda jest ładne - ale tylko jeśli masz przestrzenie wokół =. To nie zadziała POP3_SERVER_NAME=localhost.
Marcel Stör

2
@Marcel, Możesz zmienić ogranicznik używany przez awkspacje na coś innego używającego -F. Na przykład: -F "="użyje =jako separatora we wspomnianym przypadku.
mattpr

7

Zastąp ppolecenie zastąpieniem, które usuwa niechcianą część wiersza.

sed -n '3 s/^[^=]*= *//p' installation.sh

Możesz dopasować wiersz według słowa kluczowego, a nie pozycji.

sed -n 's/^ *POP3_SERVER_NAME *= *//p' installation.sh

6

Wygląda na to, że masz plik konfiguracyjny. To, co możesz zrobić, jest podobne do tego, co sugeruje Adam Siemeon / slm:

sed -nr 's/[^=]+=\s*(.+)$/\1/p' filename

gdzie [^=]nie obejmuje wszystkich znaków „=”, +mówi jeden lub więcej tego samego rodzaju charakteru, to następnie rzeczywiste =, \swszystkie spacje (łącznie z kartami \ti nowych linii \n, \r\ni gładkie przestrzenie „”, natomiast *środki zero lub więcej tego samego rodzaju nawiasy złapać co jest w środku, aby umieścić dobrane sekwencje znaków w \ 1, \ 2, ..., \ n zastępcze zamienne, $oznacza koniec linii Wynika to typowy schemat zastępczy:. s/.../.../modifiers. opcja wiersza poleceń-r oznacza rozszerzona składnia -nwyrażeń regularnych (dla wygody) i oznacza, że ​​nic nie wypisuje, dopóki nie zostanie zażądane w sposób wyraźny. pModyfikator wypisuje wynik.

Możesz dokonać globalnego wyszukiwania za pomocą gmodyfikatora, takiego jak:

sed -nr 's/[^=]+=\s*(.+)$/\1 /pg' filename  # note the space after \1

aby uzyskać ciąg rozdzielony ' '(może być \n, \talbo co cię mieć), które można łatwo przetwarzać.

Oba są poprawne, pod warunkiem, że twoje wartości poprzedzone znakiem równania rozciągają się do końca linii i nie są poprzedzone komentarzami lub innymi znakami z semantyką odbiegającą od prostej „wartości”.


Edytować:

Nie mogę tutaj jeszcze komentować postów innych osób. Aby wskazać linię, podaj numer linii, w twoim przypadku 3, przed slub przed znakiem inicjującym cytat (tak jak w vimie).

sed -nr '3s/[^=]+=\s*(.+)$/\1/p' filename

Proszę spojrzeć na info sed. Na przykład szczególnie interesują Cię 3.2 i 4.7.


5
echo "POP3_SERVER_NAME = localhost" | sed 's/.*= //'
localhost

Lub jeśli masz zawartość w pliku:

sed 's/.*= //' somefile.txt
localhost

ok, ale przeczytałem w swoim pliku w ten sposób: sed -n '3p' installation.sh
Mercer

2
@Mercer - zobacz aktualizacje, które dodałem do odpowiedzi.
slm

@Adam Siemion - dziękuję, ale jak wskazać numer linii?
Mercer

4

Możesz użyć polecenia cięcia, ustawiając delimetr na „=”, a następnie wydrukować drugie pole w następujący sposób:

cut -d'=' -f2

3

Można to zrobić na wiele sposobów, zważywszy, że plik jest nazywany foobar :

Określ wzór do wyszukania:

PAT=POP3_SERVER_NAME

Wyodrębnij za pomocą sed

sed -n "/$PAT/p" foobar | sed "s/$PAT = //"

Lub używając sedicut

sed -n "/$PAT/p" foobar | cut -d' ' -f3

2

Piękno Linux / Unix polega na tym, że zwykle istnieje więcej niż jeden sposób, aby coś osiągnąć. W przypadku operacji istnieją co najmniej cztery różne sposoby wyodrębnienia nazwy serwera POP z pliku:

  1. grep POP3_SERVER_NAME installation.sh | cut -d'=' -f2
  2. grep POP3_SERVER_NAME installation.sh | awk '{print $3}'
  3. grep POP3_SERVER_NAME installation.sh | sed 's/.*= //'
  4. sed -n 's/^.*POP3_SERVER_NAME = //p' installation.sh
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.