Jak mogę „cat” plik i usunąć skomentowane linie?

29

Chciałbym wiedzieć, czy istnieje sposób, w jaki mógłbym catzapisać php.inii usunąć wszystkie wiersze zaczynające się od;

Na przykład, jeśli plik zawierał to:

;   - Show all errors, except for notices
;
;error_reporting = E_ALL & ~E_NOTICE
;
;   - Show only errors
;
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
;
;   - Show all errors except for notices
;
error_reporting  =  E_ALL & ~E_NOTICE

i uruchomiłem prawidłowe polecenie cat | {remove comments command}, a następnie skończyłem na:

error_reporting  =  E_ALL & ~E_NOTICE

Uwaga - Sądziłem, że catbędzie najlepszym sposobem, aby to zrobić, ale jestem naprawdę w porządku z odpowiedzią przy użyciu innego narzędzia jak awk, sed, egrep, itd.

cwd
źródło
Co powiesz na coś takiego error_reporting = E_ALL & E_NOTICE ; Show all errors, except for notices? Czy komentarz również powinien zostać usunięty?
CVn z
@ MichaelKjörling - Nic mi nie jest z linijką rozpoczynającą się od usunięcia komentarza
cwd
1
catto narzędzie do łączenia plików. grepto narzędzie do filtrowania linii na podstawie wzorów. sedi awkmoże również modyfikować te linie.
Stéphane Chazelas

Odpowiedzi:

31

Możesz użyć:

sed -e '/^;/d' php.ini
favadi
źródło
25

Nie musisz przesyłać pliku przez grep, grep przyjmuje nazwy plików jako argumenty linii poleceń.

grep -v '^#' file1 file2 file3

wypisze wszystkie linie Z WYJĄTKIEM tych, które zaczynają się od # char. możesz zmienić znak komentarza na cokolwiek chcesz.

Jeśli masz więcej niż jeden znak komentarza (zakładając, że jest on na początku wiersza)

egrep -v '^(;|#|//)' filelist
bsd
źródło
2
Kolejnym, który zrobiłem, a który zawsze mnie tkwił, był grep '^[^;]' filename. Nie mogę jednak mówić o jego przenośności!
Jodie C,
@JodieC, który jest przenośny, ale usuwa również puste linie (co jest często pożądane). Standardowy odpowiednik egrepto grep -E. Można również użyćgrep -ve '^[;#]' -e '^//'
Stéphane Chazelas
9

egrepmoże zaoszczędzić ci korzystania z cat. Innymi słowy, stwórz mniej procesów ( egrepvs cat+ egrep) i używaj mniej buforów (potok od catdo egreppotok bez).

Zasadniczo dobrym pomysłem jest ograniczenie użycia, catjeśli po prostu chcesz przekazać plik komendzie, która może go odczytać samodzielnie.

Powiedziawszy to, następujące polecenie usunie komentarze, nawet jeśli są wcięte spacjami lub tabulatorami:

egrep -v '^ [[: blank:]] *;' plik.ini
nrolans
źródło
Zabawne, że łączysz nowy format wyrażenia regularnego [[ klasy znaków ]] z użyciem egreppolecenia przestarzałego przez co najmniej dekadę.
mikeserv
Interesujące ... aktualne dokumenty na gnu.org/software/grep/manual/html_node/... obejmują klasy POSIX.
Jack Wasey,
7
egrep -v '^;|^$' $file

wyklucza to linie rozpoczynające się od „;” i puste linie.

w wyrażeniu regularnym ^wskazuje początek linii i $koniec linii, więc ^$określa linie, w których znak początku linii i znak końca linii znajdują się obok siebie.

Tim Kennedy
źródło
więc jeśli czytam to prawo, może to usunąć skomentowane wiersze, ale także puste wiersze?
cwd
1
@cwd Tak. Nie jestem pewien, dlaczego uwzględnił oba, ale jeśli chcesz tylko usunąć skomentowane linie, po prostu użyjegrep -v '^;'
Michael Mrozek
4
egrep lubi też pliki (mniej procesów i używanych buforów), a niewielką premią byłoby usunięcie wciętych komentarzy:egrep -v '^[[:blank:]]*;' file.ini
nrolans
10
Potrzebujemy plakietki „bezużyteczne użycie kota”.
Simon Richter,
@nrolans - wygląda jak popularny komentarz, dlaczego nie dać odpowiedzi?
cwd
2

Prosty awkjednowarstwowy awk '/^;/{next}1' input_filepowinien załatwić sprawę.

[jaypal:~/Temp] cat file
;   - Show all errors, except for notices
;
;error_reporting = E_ALL & ~E_NOTICE
;
;   - Show only errors
;
;error_reporting = E_COMPILE_ERROR|E_ERROR|E_CORE_ERROR
;
;   - Show all errors except for notices
;
error_reporting  =  E_ALL & ~E_NOTICE

[jaypal:~/Temp] awk '/^;/{next}1' file
error_reporting  =  E_ALL & ~E_NOTICE
[jaypal:~/Temp] 
jaypal singh
źródło
3
Prawidłowe, ale pełne słów. Wystarczy awk '!/^;/' input_file.
manatwork
2

Podobnie jak Jaypal, najprawdopodobniej również użyłbym awkdo tych celów. Gorzej jest wspomnieć, że Perl jest czasem bardzo przydatny do takich celów:

cat data.txt | perl -lne "print unless /^;/"

Wyrażenia regularne Perla mają większą moc niż w awk i czasami możesz ich potrzebować.

shabunc
źródło
+1 za perla, chociaż kot i -l są zbędne, więc prostsze wywołanie toperl -ne 'print unless /^;/' data.txt
Simon Whitaker
@ Simone Whitaker, tak, masz rację - nawyk pisać to tak, jak ja piszę, i warto o tym wspomnieć.
shabunc,
1
Jasne. W rzeczywistości uważam, że catdziała dobrze w tych przykładach, jeśli weźmiesz to pod uwagę jako bardziej ogólne określenie „cokolwiek generującego tekst na STDOUT”. Rury uniksowe są najlepsze od krojonego chleba, imho. :)
Simon Whitaker,
2

Opracowanie odpowiedzi @ shabunc, używa Perla do usuwania komentarzy (w tym komentarzy śródliniowych), a następnie drukowania dowolnych linii zawierających cokolwiek innego niż białe znaki.

$ perl -ne 's/;.*//; print if /\S/' data.txt

Wyjaśnienie:

  • s/;.*//używa operatora podstawienia ( s/<regex>/<replacement>/) w celu zastąpienia wystąpień średnika i wszystkiego po nim w wierszu z pustym łańcuchem.
  • print if /\S/wypisuje linię, jeśli pasuje do wyrażenia regularnego \S, który jest klasą znaków pasującą do wszystkich znaków niebiałych spacji.
Simon Whitaker
źródło
1

Oto jeden, którego używam, wystarczy zastąpić ';' ze znakiem komentarza (np. „#” dla wielu plików konfiguracyjnych usługi UNIX):

grep -Ev '^[[:space:]]*;|^$' chan_dahdi.conf.sample | sed 's/;.*$//'

Pozbywa się to wszystkich komentarzy obejmujących całą linię (nawet jeśli mają wiodące białe znaki) oraz wszelkich komentarzy, które kończą wiersze bez komentarzy, i zwięźle usuwa również puste linie z danych wyjściowych. Może to być możliwe bez rurociągu (mój sed- lub awk-fu nie jest wprawdzie świetny), ale tak łatwo mi to zrozumieć (i pamiętać), pomyślałem, że opublikuję to tutaj.

Trey Blancher
źródło
1

Przykład pokazuje tylko linie + nie pokazuje nowych linii ani pustych linii:

$ egrep -v '^(;|#|//)' /etc/ssh/sshd_config | tr '\n' ' '

 Protocol 2    SyslogFacility AUTHPRIV      PasswordAuthentication yes  ChallengeResponseAuthentication no   GSSAPIAuthentication yes GSSAPICleanupCredentials yes  UsePAM yes  AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE AcceptEnv XMODIFIERS  X11Forwarding yes   Subsystem sftp    /usr/libexec/openssh/sftp-server 

LUB

$ egrep -v '^(;|#|//|$)' /etc/ssh/sshd_config    

Protocol 2
SyslogFacility AUTHPRIV
PasswordAuthentication yes
ChallengeResponseAuthentication no
GSSAPIAuthentication yes
GSSAPICleanupCredentials yes
UsePAM yes
AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
AcceptEnv XMODIFIERS
X11Forwarding yes
Subsystem   sftp    /usr/libexec/openssh/sftp-server

źródło
2
Zastosowanie egrepjest od dawna przestarzałe. grep -Eto polecenie, którego tu szukasz.
mikeserv
0
egrep -v ^'(#|$)' file.txt

Usuwa wszystkie komentarze i puste wiersze z pliku.txt

Nikola
źródło
2
Powinieneś rozważyć poszerzenie swojej odpowiedzi o nieco więcej informacji dla niewtajemniczonych (np. Dokładnie to, czego używa regex).
HalosGhost
egrepjest amortyzowane. Użyj grep -Evzamiast tego.
Yokai
0

Usunie również puste linie

grep -E -v "^\s*($|;)" php.ini
Fedir RYKHTIK
źródło
0

możesz użyć następującego polecenia, aby zapisać linie, z wyjątkiem pustych linii i linii zaczynających się od # w nowym pliku

cat <file to be read> | egrep -v '^#|^$' > <file to be written at>

KawaiKx
źródło
catRura bezużyteczna i egrepjest amortyzowana i należy ją zastąpić grep -Erozszerzonymi wyrażeniami lub po prostu grep -v.
Yokai