특정 열에 특정 값이있는 행을 grep하는 방법은 무엇입니까?


9

다음과 같은 파일이 있습니다

  200.000    1.353    0.086
  200.250    1.417    0.000
  200.500    1.359    0.091
  200.750    1.423    0.000
  201.000    1.365    0.093
  201.250    1.427    0.000
  201.500    1.373    0.093
  201.750    1.432    0.000
  202.000    1.383    0.091
  202.250    1.435    0.000
  202.500    1.392    0.087
  202.750    1.436    0.000
  203.000    1.402    0.081
  203.250    1.437    0.001
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  

첫 번째 열에 소수점 .000 및 .500 만있는 행만 grep하고 싶습니다. 그래서 출력은 다음과 같습니다

  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045  

2
충분히 쉬워 보입니다. 지금까지 뭐 해봤 어? 코드에 어떤 문제가 있습니까?
John1024

아마 당신을 위해 쉽지만 grep '.000' 와 함께 시도 | grep '.005' 이지만 다른 열에서 동일한 값을 갖는 행을 정렬합니다.
Mohsen El-Tahawy

3
아주 좋아요 문제를 직접 해결하려는 정직한 시도를 보이면 여기 사람들이 훨씬 더 동정심이 있습니다. 귀하의 의견에 코드가 표시됩니다. 나중에 질문에 이와 같은 시도를 포함하면 더 나은 응답을 더 빨리 얻을 수 있습니다.
John1024

답변:


14

grep을 사용하지 않습니다. 사용하십시오 awk.

"your data" | awk '$1 ~ /\.[05]00/'

아주 좋아요 작성된 바와 같이, 코드는 소수점 뒤에 정확히 3 자리가 있어야합니다. 사용하는 것이 더 강력 할 것 awk '$1 ~ /\.[05]0*$/'입니다.
John1024

1
@ John1024, 실제로 코드를 작성한 것처럼 소수점 이하 세 자리 이상이 있어야 합니다. 나는쪽으로 기울어 것 awk '$1 ~ /\.[05]00$/'나는 그 변수의 소수점이 입력으로 예상된다 생각하는 이유가없는 한, 자신은 (정확히 3 자리가 필요합니다).
와일드 카드

2
@Wildcard 세 개 이상이 있으면 코드가 실패 할 수 있습니다. 예를 들면 다음과 같습니다 echo 0.5001 | awk '$1 ~ /\.[05]00/'.. 정확히 3 개가있는 경우에만 안정적으로 작동합니다 .
John1024

4
awk '$1 ~ /\.[50]00/ { print $0 }' myFile.txt

첫 번째 열 $1/\.500|\.000/점 과 일치 하고 문자 ~는 부분적으로 일치 하는 정규 표현식이 아닌 리터럴 점으로 이스케이프됩니다.$0


2
포함 할 이유가 없습니다 { print $0 }. 이것이 Awk의 기본 동작입니다.
와일드 카드

4

첫 번째 열에 소수점 .000 및 .500이있는 행만 grep하고 싶습니다.

내 첫 생각

grep '^ *[0-9][0-9][0-9]\.[50]00' filename

WSL을 사용한 빠른 테스트

$ head testdata
              200.000    1.353    0.086
              200.250    1.417    0.000
              200.500    1.359    0.091
              200.750    1.423    0.000
              201.000    1.365    0.093
              201.250    1.427    0.000
              201.500    1.373    0.093
              201.750    1.432    0.000
              202.000    1.383    0.091
              202.250    1.435    0.000
$ grep '^ *[0-9][0-9][0-9]\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

이것을 표현하는 더 간결한 방법이 있습니다.

$ grep -E '^ *[0-9]{3}\.[50]00' testdata
              200.000    1.353    0.086
              200.500    1.359    0.091
              201.000    1.365    0.093
              201.500    1.373    0.093
              202.000    1.383    0.091
              202.500    1.392    0.087
              203.000    1.402    0.081
              203.500    1.412    0.073
              204.000    1.423    0.065
              204.500    1.432    0.055
              205.000    1.441    0.045

첫 번째 열에 3 자리 정수 이외의 부분이있을 수있는 경우

grep -E '^ *[0-9]+\.[05]00' testdata

경우에 따라 [:digit:]대신 사용해야 할 수도 있습니다 [0-9].

등등.

man grep 당신의 친구입니다.


이 사용법은 grep내 것보다 사용하기 쉽습니다. 나는 이것을 처음 본다면 답을 게시하지 않았을 것입니다. 좋은 작업!
Yokai

2

사용 사례에 따라 실제 숫자 연산을 사용할 수도 있습니다.

$ awk '{a = $1 % 1} a == 0 || a == 0.5' /tmp/foo
  200.000    1.353    0.086
  200.500    1.359    0.091
  201.000    1.365    0.093
  201.500    1.373    0.093
  202.000    1.383    0.091
  202.500    1.392    0.087
  203.000    1.402    0.081
  203.500    1.412    0.073
  204.000    1.423    0.065
  204.500    1.432    0.055
  205.000    1.441    0.045

BSD awk (OSX El Capitan, 20070501) 및 GNU awk 4.1.4로 테스트되었습니다.


1
경고 : 부동 소수점의 정확한 동등성을 테스트하면 (awk가 사용하는) 값에 소수 부분이 없거나 (너무 크지 않은) 소수 부분이 '이진'(정확히 반, 분기 등))이 Q의 데이터에는 적용되지만 시작되지 않은 것과 유사한 다른 많은 것은 아닙니다.
dave_thompson_085

1
실제로 @ dave_thompson_085이지만 gawk를 사용하면 임의의 정밀도 산술을 사용할 수 있습니다.
muru November


2

awk:

$>awk '$1%.5==0' data.tsv 
200.000 1.353   0.086
200.500 1.359   0.091
201.000 1.365   0.093
201.500 1.373   0.093
202.000 1.383   0.091
202.500 1.392   0.087
203.000 1.402   0.081
203.500 1.412   0.073
204.000 1.423   0.065
204.500 1.432   0.055
205.000 1.441   0.045

mlr:

$>mlr --ifs tab --onidx filter '$1%.5==0' data.tsv 
200.000 1.353 0.086
200.500 1.359 0.091
201.000 1.365 0.093
201.500 1.373 0.093
202.000 1.383 0.091
202.500 1.392 0.087
203.000 1.402 0.081
203.500 1.412 0.073
204.000 1.423 0.065
204.500 1.432 0.055
205.000 1.441 0.045

2

좋아, 조금 늦게 내 기여를 추가하지만 그만한 가치가 있다고 생각합니다.

영업 당 충족시킬 수있는 요구 사항의 진수 값 갖는 첫 번째 열입니다 .000또는 .500만. 범위 또는 길이를 기준으로 선행 값에 대한 규정이 없습니다. 견고성을 위해이 첫 번째 열의 이전에는 공백이 아닌 문자 (또는 더 이상 첫 번째 열이다)와이없는 것을 제외하고는 아무것도에 의해 제한되는 것으로 가정해서는 안된다 첫 번째 열의 내용이 있다는 것이다 소수점을 가지고 ., 어딘가에.

영업 이익은 사용하고자한다 grep할 수있는 유일한 것은 일치하는 패턴을 생성하므로, 일치가 발견되면 전체 라인을 출력합니다, 모든단지 무엇을 요구된다.

단순성 자체를 사용할 이유가 sed없거나 awk`grep '으로 소스를 파일이나 파이프로 처리 할 수 ​​있습니다.

grep파일 사용grep '^[^.]*\.[05]0\{2\}\s' the_file.txt

grep파이프 사용에서my_command | grep '^[^.]*\.[05]0\{2\}\s'

패턴은 다음 ^과 같습니다. , 줄의 시작 부분에서 시작합니다. [^.], 10 진수가 아닌 문자와 일치합니다. *가능한 한 여러 번 (없음 포함); \.소수점과 일치합니다. [05], 5 또는 0과 일치합니다. 0\{2\}, 2 개 더 0을 일치시킵니다 (개방형 및 폐쇄 형 괄호 앞의 백 슬래시는 쉘이 괄호 확장을 시도하지 못하도록합니다). \s, 공백 문자를 일치시킵니다 (열의 끝을 의미 함-다른 사용 사례에서 사용하려면 열 구분 기호 (일반적으로 쉼표, 세미콜론 또는 탭 \t)로 바꾸십시오 ).

이것은 OP가 요청한 것과 정확히 일치 합니다 . 그것은 것입니다 하지 일치 .5000또는 .0000정확히 다음에 5 제로의 패턴 외모 때문에 수치 적으로 동등한 비록 더 제로 공백 하였다. 그것이 중요하다면, 지금까지의 다른 모든 대답은 테스트 자리 이후 1보다 큰 0과 일치한다는 점에서 실패합니다. 그리고 FloHimself으로 대답을 제외하고, 그들은 일치 아무것도 두 번째 열에서 시작을 .000 하거나 .500, 포함 .0003하고 .500T, 그리고 FloHimself에 의해 하나는 수학적으로 동등하다 아무것도 일치 .0하고.50이 몇 개이든 상관 없습니다. 마지막은 OP가 언급 한 것과 일치하지 않지만 OP가 필요로하는 것과 일치 할 가능성이 있습니다.

마지막으로 awkOP가 요청했지만 전력 및 속도 가 필요한 grep경우 명령은 다음과 같습니다.

파일로 awk '$1 ~ /[^.]\.[05]0{2}$/' the_file.txt

파이프로 my_command | awk '$1 ~ /[^.]\.[05]0{2}$/'


1

grep 사용을 고집하면 이것이 효과가있을 수 있습니다. 제공 한 첫 번째 출력을 "file.txt"라는 텍스트 파일에 저장 한 후 다음 명령을 사용했습니다.

grep -e '2[^ ]*.000' file.txt & grep -e '2[^ ]*.500' file.txt

출력은 다음과 같습니다.

200.000    1.353    0.086
200.500    1.359    0.091
201.500    1.373    0.093
201.000    1.365    0.093
202.500    1.392    0.087
202.000    1.383    0.091
203.500    1.412    0.073
203.000    1.402    0.081
204.500    1.432    0.055
204.000    1.423    0.065
205.000    1.441    0.045

출력이 이미 파일에 있으면 텍스트 파일로 출력을 저장할 필요가 없습니다. 그러나 파일에 저장되지 않은 경우 데이터를 내가 제공 한 grep 명령으로 파이프 할 수 있으며 적어도 첫 번째 숫자 2가 첫 번째 열에서 더 이상 a가 아닌 때까지 작동해야 합니다 2. 이 시점에서 grep 명령을 적절한 문자로 업데이트하여 올바르게 인쇄해야합니다.

이 이중 grep명령으로 일어나는 것은 첫 번째 명령이 운영자 grep와 함께 백그라운드로 전송된다는 것 &입니다. 백그라운드로 전송되면 다음 grep명령이 즉시 실행되어 균일 한 출력을 제공합니다. 보다 쉽게 ​​수행하기 위해 완료해야하는 작업을 수행하려면 다른 사람이 제공하고 사용 awk하거나 예를 따라야합니다 sed.

(편집하다)

이것은 당신의 필요에 맞는 최고의 grep 사용법은 아니지만, 조금 놀아도 grep에 대한 느낌이 좋아질만큼 충분해야합니다.


첫 번째 프로세스는 백그라운드에서 실행되지만 백그라운드에서 실행되지만 상당히 많은 데몬이 적용되지 않습니다 . 그리고 입력과 동일한 순서로 출력을 생성 할 가능성은 거의 없습니다. 아주 작은 예에서도 이미 세 번째 줄에서 잘못되었습니다.
dave_thompson_085

그는 출력이 특정 순서로 필요하다고 언급하지 않습니다. 단지가 특정 될 필요가 있다고 .500하고 .000첫 번째 열의. 최소에서 최대로 특정 순서로해야하는 경우 쉽게 수행 할 수 있습니다. 그러나, 인쇄되는 첫 번째 열의 처음 3 자리는 최소한 가장 큰 순서입니다. 즉,의 결과 2[^ ]*.0002[^ ]*.500. OP가 요청한 내용에 매우 적합합니다.
Yokai

또한 내가 제공 한 명령에 대한 효율성 면책 조항에 대한 편집 내용에 유의하십시오.
Yokai
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.