Як я можу "котити" файл та видаляти коментовані рядки?


29

Мені хотілося б знати, чи є спосіб, який я можу catподати як php.iniі видалити всі рядки, починаючи з;

Наприклад, якщо файл містив це:

;   - 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

і я запустив правильну команду cat | {remove comments command}, тоді я закінчив би:

error_reporting  =  E_ALL & ~E_NOTICE

Примітка - Я припускав , що catбуде найкращим способом зробити це , але я на самом деле добре з відповіддю з допомогою іншої утиліти , як awk, sed, egrepі т.д.


А як щодо чогось error_reporting = E_ALL & E_NOTICE ; Show all errors, except for notices? Чи слід також видаляти коментар у такому випадку?
CVn

@ MichaelKjörling - Я справді прекрасний, просто рядки, що починаються з видалення коментарів
cwd

1
catє інструментом для об'єднання файлів. grep- це інструмент для фільтрації ліній на основі шаблонів. sedа awkтакож може змінювати ці рядки.
Стефан Шазелас

Відповіді:



25

Вам не потрібно передавати файл через grep, grep приймає назви файлів як аргументи командного рядка.

grep -v '^#' file1 file2 file3

буде надрукувати всі рядки, крім тих, які починаються з # char. ви можете змінити графіку коментарів на все, що завгодно.

Якщо у вас є більше одного коментаря (якщо припустити його на початку рядка)

egrep -v '^(;|#|//)' filelist

2
Ще один, який я робив, що завжди був зі мною grep '^[^;]' filename. Я не можу говорити про його портативність!
Джоді C

@JodieC, це портативно, але також видаляє порожні рядки (що часто хочеться). Стандартний еквівалент egrepє grep -E. Можна також скористатисяgrep -ve '^[;#]' -e '^//'
Стефан Шазелас

9

egrepможе заощадити використання cat. Іншими словами, створіть менше процесів ( egrepvs cat+ egrep) і використовуйте менше буферів ("pipe from catto egrepvs no pipe").

Як правило, добре використовувати обмеження на використання, catякщо ви просто хочете передати файл команді, яка може прочитати його самостійно.

З урахуванням цього, наступна команда видалить коментарі, навіть якщо вони позначені пробілами або вкладками:

egrep -v '^ [[: blank:]] *;' file.ini

Смішно, що ви комбінуєте новіший формат регексу [[ класів символів ]] з використанням egrepкоманди, яка застаріла принаймні на десятиліття або близько того.
mikeserv

Цікаві ... поточні документи на gnu.org/software/grep/manual/html_node/… включають класи POSIX.
Джек Уейсі

7
egrep -v '^;|^$' $file

це буде виключати рядки, що починаються з ';' та порожні рядки.

у регулярному вираженні ^вказує початок рядка та $кінець рядка, тому ^$визначає рядки, де початок символу рядка та кінець символу рядка знаходяться прямо поруч.


тож якщо я читаю це право, це може видалити коментовані рядки, а також порожні рядки?
cwd

1
@cwd Так. Я не впевнений, чому він включив обидва, але якщо ви хочете лише видалити коментовані рядки, просто використовуйтеegrep -v '^;'
Michael Mrozek

4
egrep також любить файли (менше використовуються процеси та буфери), і невеликим бонусом буде видалити також відступні коментарі:egrep -v '^[[:blank:]]*;' file.ini
nrolans

10
Нам потрібен знак "марного використання котячого".
Саймон Ріхтер

@nrolans - схожий на популярний коментар, чому б не зробити це відповіддю?
cwd

2

Простий awkоднолінійний awk '/^;/{next}1' input_fileповинен зробити свою справу.

[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] 

3
Правильно, але багатослівно. Просто awk '!/^;/' input_fileдостатньо.
маніпуляція

2

Як і Джейпал, я також, швидше за все, використовував би awkдля цих цілей. Гірше зазначити, що Perl іноді досить зручний для таких цілей:

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

Regexps Perl є більш потужним порівняно з одним із awk, і іноді вони можуть вам знадобитися.


+1 за perl, хоча і кішка, і -l, і зайві, тому простішим викликом єperl -ne 'print unless /^;/' data.txt
Simon Whitaker

@Simone Whitaker, так, ти маєш рацію - це просто звичка писати це так, як я пишу, і це варто згадати.
shabunc

1
Вірна думка. Насправді, я думаю, що catв цих прикладах добре працює, якщо ви розглядаєте це як проксі для більш загального "що-небудь генеруючого тексту в STDOUT". Труби Unix - найкраща річ, оскільки нарізаний хліб, imho. :)
Саймон Уітакер

2

Ознайомлення з відповіддю @ shabunc, це використовує Perl, щоб знімати коментарі (включаючи вбудовані коментарі), а потім друкувати будь-які рядки, що містять що-небудь, крім пробілу.

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

Пояснення:

  • s/;.*//використовує оператор підстановки ( s/<regex>/<replacement>/) для заміни екземплярів напівкрапки та всього, що йде за ним у рядку із порожнім рядком.
  • print if /\S/друкує рядок, якщо він відповідає регулярному вираженню \S, що є класом символів, який відповідає усім символам, що не містять пробілів.

1

Ось такий, який я використовую, просто підміняю ';' з символом коментаря (наприклад, "#" для багатьох файлів конфігурації служби UNIX):

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

Це позбавляється від усіх цільних рядків коментарів (навіть якщо вони мають провідні пробіли), а також будь-яких коментарів, які закінчуються рядками без коментарів, і також швидко видаляє порожні рядки з результатів. Це можливо можливо без трубопроводу (мій sed- або awk-fu, правда, не великий), але мені це так легко зрозуміти (і запам'ятати), я зрозумів, що опублікую його тут.


1

Приклад показує лише рядки + не показувати нові рядки або порожні рядки:

$ 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 

АБО

$ 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

2
Використання egrepдавно застаріло. grep -Eце команда, яку ви шукаєте тут.
mikeserv

0
egrep -v ^'(#|$)' file.txt

Знімає всі коментарі та порожні рядки з file.txt


2
Спробуйте розширити свою відповідь трохи більше інформації для непосвячених (наприклад, саме те, що робить регулярний вираз, який ви використовуєте).
HalosGhost

egrepамортизується. Використовуйте grep -Evзамість цього.
Йокай


0

Ви можете використовувати наступну команду для збереження рядків, виключаючи порожні рядки та рядки, починаючи з # у новому файлі

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


Марно catтруба egrepамортизується і підлягає заміні grep -Eна розширені вирази або просто grep -v.
Йокай
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.