grep은 패턴을 따르지 않는 행을 찾습니다.

grep은 패턴을 따르지 않는 행을 찾습니다.

특정 패턴과 일치하지 않는 파일의 모든 줄을 찾으려고 합니다.

한동안 나는 명령이 중복되는 historyGNU(버전 4 및 5)를 사용하는 데 bash문제가 있었습니다 . 나는 .bashrc다음과 같은 줄이 있기 때문이라고 생각합니다.

 PROMPT_COMMAND="history -a; history -n; $PROMPT_COMMAND"

screen터미널 멀티플렉서( 및/또는 ) 를 사용하고 있으므로 tmux위 명령이 여러 번 실행됩니다 echo $PROMPT_COMMAND.history -a; history -n; history -a; history -n;

어떤 경우에는(특히 다른 창/창/프레임/버퍼에서 동시에 작업을 수행할 때) 마지막으로 입력한 명령이 내 에 있었습니다 ~/.bash_history.

#1596110297
yadm list -a | xargs -t ls -l
yadm list -a | xargs -t ls -l

말할 필요도 없이 이것은 성가시다. 방금 (희망적으로) 문제에 대한 해결책을 찾았지만 history(명령을 로 변경하여 PROMPT_COMMAND="history -a; history -n) 수정: 이 문제는 해결되지 않았습니다 history.

이제 중복 항목을 제거하고 싶습니다.

#그래서 저는 현재 그것으로 시작하는 줄과 그 뒤의 줄을 제외한 모든 것에 태그를 지정하는 정규식을 찾으려고 노력하고 있습니다 . 내 첫 번째 아이디어는 grep -v(선택 반전)과 grep -A 1(패턴 일치 후 추가 행 가져오기)를 결합하는 것이었습니다. 하지만

grep -v "^#" -A 1 ~/.bash_history

기대했던 결과를 얻지 못했습니다.

제 질문은: 를 사용하여 이 작업을 수행하는 방법을 아는 사람이 있습니까 grep? 그렇지 않은 경우: 이 작업을 수행하기 위해 다른 도구( sed, , ...) 를 어떻게 사용할 수 있습니까 awk?

답변1

내가 이해한 바로는 grep -v "^#" -A 1해시 기호로 시작하지 않고 각 줄 뒤에 한 줄씩 인쇄하는 것을 의미합니다. 그러나 반대 결과를 원하지 않는다면 다음 줄을 인쇄하십시오.하다파운드 기호로 시작한 다음 줄로 시작하시겠습니까?

테스트 파일이 주어지면:

#123
echo this
echo this
#456
echo that
echo that
echo that
#789
echo third

grep -A1 ^# history.txt |grep -vxFe --인쇄:

#123
echo this
#456
echo that
#789
echo third

두 번째는 grep그룹 구분 기호 없이 인쇄하는 것입니다 grep -A.

또는 uniq history.txt동일한 줄의 각 연속 그룹에서 하나만 인쇄해야 합니다.

답변2

Raku 사용(옛 Perl6)

이는 다양한 스크립팅 언어에서 사용할 수 있는 "트리거" 연산자의 작업인 것 같습니다. 다음은 Raku 프로그래밍 언어(이전 Perl6)를 사용한 답변입니다. 먼저 더 넓은 테스트 파일을 만듭니다.

$ cat repeated_log.txt
#1596110297_1
A_yadm list -a | xargs -t ls -l
B_yadm list -a | xargs -t ls -l
#1596110297_2
C_yadm list -a | xargs -t ls -l
D_yadm list -a | xargs -t ls -l
E_yadm list -a | xargs -t ls -l
#1596110297_3
F_yadm list -a | xargs -t ls -l
G_yadm list -a | xargs -t ls -l
H_yadm list -a | xargs -t ls -l
I_yadm list -a | xargs -t ls -l
#1596110297_4
#1596110297_5

fff이제 Raku의 트리거 연산자를 사용하여 "sed와 유사한" 동작을 달성하는 코드 줄을 작성하세요. 정규식에서 ^^리터럴 "#" 문자 가 (줄 시작 부분에) 표시되는 첫 번째 줄에 대해 캡처가 켜져 있습니다. 일단 켜면 캡처는 첫 번째 정규식을 무시하고 두 번째 정규식에 대해 평가하여 ^^"#" 문자가 누락된(줄 시작 부분에) 줄과 일치하는 항목을 찾으면 닫힙니다. "음수" 정규식은 다음 코드에서 구현됩니다 <-[#]>. 이는 음수 "열거 문자 클래스"이며 Raku 언어의 실제 기능입니다.

$ raku -ne '.put if /^^ "#" / fff /^^ <-[#]> /;' repeated_log.txt
#1596110297_1
A_yadm list -a | xargs -t ls -l
#1596110297_2
C_yadm list -a | xargs -t ls -l
#1596110297_3
F_yadm list -a | xargs -t ls -l
#1596110297_4
#1596110297_5

실제로 첫 번째 정규식(중위 연산자의 왼쪽 fff)은 <+[#]>보다 병렬적인 구성을 가능하게 하기 위해 긍정적인 "열거 문자 클래스"를 사용하여 작성될 수 있습니다.

$ raku -ne '.put if /^^ <+[#]> / fff /^^ <-[#]> /;' repeated_log.txt
#1596110297_1
A_yadm list -a | xargs -t ls -l
#1596110297_2
C_yadm list -a | xargs -t ls -l
#1596110297_3
F_yadm list -a | xargs -t ls -l
#1596110297_4
#1596110297_5

또한 하나 이상의 숫자가 뒤따르는 선행 "#"을 일치시키거나 거부하여 정규식을 개선할 수 있는 것 같습니다. 즉 <digit>+, 아래를 참조하세요.

$ raku -ne '.put if /^^ <+[#]> <digit>+ / fff /^^ <-[#]> <-digit>+ /;' repeated_log.txt
#1596110297_1
A_yadm list -a | xargs -t ls -l
#1596110297_2
C_yadm list -a | xargs -t ls -l
#1596110297_3
F_yadm list -a | xargs -t ls -l
#1596110297_4
#1596110297_5

[위의 모든 코드는 B, D, E, G, H 및 I로 시작하는 중복 줄을 제거합니다. 내가 알아차린 유일한 특이한 점은 두 개의 연속된 대상 줄(예: "#1596110297")이 출력에 표시된다는 것입니다. 그러나 입력 파일에 이러한 연속된 줄이 포함되어 있는지 확실하지 않습니다.]

https://raku.org/

관련 정보