다음과 같은 파일이 있습니다.
Marketing Ranjit Singh FULLEagles Dean Johnson
Marketing Ken Whillans FULLEagles Karen Thompson
Sales Peter RobertsonPARTGolden TigersRich Gardener
President Sandeep Jain CONTWimps Ken Whillans
Operations John Thompson PARTHawks Cher
Operations Cher CONTVegans Karen Patel
Sales John Jacobs FULLHawks Davinder Singh
Finance Dean Johnson FULLVegans Sandeep Jain
EngineeringKaren Thompson PARTVegans John Thompson
IT Rich Gardener FULLGolden TigersPeter Robertson
IT Karen Patel FULLWimps Ranjit Singh
grep 명령을 사용하여 두 번째 열에서 "John"을 검색하고 마지막 열을 검색하고 싶지만 두 번째 열의 모든 "John"에 대해 마지막 열의 출력을 원합니다.
최종 결과는 다음과 같아야 합니다.
John Thompson Cher
John Jacobs Davinder Singh
Dean Johnson Sandeep Jain
답변1
#! /bin/bash
while read line; do
if [[ ${line:11:15} =~ John ]]; then
echo " ${line:11:15} ${line:43}"
fi
done <file
답변2
grep
줄 시작 부분부터 올바른 문자 수를 일치시켜 선택을 수행할 수 있습니다.
grep -E '^.{11,22}John'
John
11~26열 범위 내에서 시작하고 끝나야 합니다.
특정 열을 공백으로 바꾸는 것은 grep의 기능을 벗어납니다. GNU grep을 사용하면 일치하는 부분만 출력할 수 있지만 -o
사이에 추가 공백이 있는 두 열을 결합할 수는 없습니다.
답변3
tab=$(printf '\t')
cut -c12-26 file | paste - file | grep "^[^$tab]*John" | cut -c1-16,60-
Giles가 말했듯이 혼자서는 할 수 없습니다 grep
. re와 일치하는 행을 인쇄하는 ( 명령)을 grep
나타냅니다 .g/re/p
ed/ex/vi
답변4
방금 표시된 솔루션의 몇 가지 팁을 결합해 보겠습니다.
Stephen + Giles에서:
grep -E '^.{11,22}John' source.txt | cut -c12-26,44-
# or, if you want only "John " and not Johnson, add a space after John.
grep -E '^.{11,22}John ' source.txt | cut -c12-26,44-
/bin/grep
여기서도 and 를 사용해야 합니다 /bin/cut
.
Giles + Hauke에서:
grep -E '^.{11,22}John' source.txt | while read line; do echo "${line:11:14} ${line:43}"; done
/bin/grep
여기서도 and 를 사용해야 합니다 echo
. 현대 껍질에서는 echo
다음과 같은 것을 찾을 수 있습니다내장 명령따라서 덜 필요합니다.
Hauke의 솔루션은 설치 프로그램 측면에서 더 저렴합니다. 질문에서 원하는 대로 echo
(내장형 bash
)만 필요하지만 그조차도 필요하지 않습니다 ./bin/grep
고쳐 쓰다잠시 동안 놀자.
일상생활에서 우리는 달리고 있다파편즉석에서 생성되어 다시는 사용되지 않을 수 있는 코드는 지출이 항상 편리한 것은 아닙니다.우리 인간 나이최적화하거나 다른 변형을 시도해보세요...그러나"Crazy Years"의 세멜: 반면에 이것이 case-study question
, 어쩌면 심지어숙제확실하지 않습니다. IMHO, 이 광학에서는 다양한 방법과 솔루션이 모두 유용합니다.
많은 수의 행에 대해서는 일련의 쉘 명령보다 컴파일된 프로그램을 사용하는 것이 더 낫다(빠르다)는 데 모두 동의할 수 있는 것 같습니다. 그런데 뭐가 큰가요? 나는 숫자(및 그래프)가 단어보다 아이디어를 더 잘 표현한다고 생각합니다. 살펴보겠습니다.
여기레시피: 라인 수가 증가하는 파일 세트,질소, 준비해. 여기에 게시된 원문 11줄 중 각 줄을 무작위로 추출했습니다.
가치질소사용되는 것은 입니다
11 22 55 110 220 550 1100 2200 5500 11000 110000 1100000 11000000
.
이것파편테스트된 내용은 다음과 같습니다.
Cut+Paste+Grep+Cut
tab=$(printf '\t') ; cut -c12-26 file | paste - file | grep "^[^$tab]*John" | cut -c1-16,60-
이것-녹색Only Grep
-파란색grep -E '^.{11,22}John' source.txt
.grep
필요에 따라 출력 형식을 지정하지 않습니다 .- 이
Grep+Cut
빨간색[grep -E '^.{11,22}John' source.txt | cut -c12-26,44-
]. - - 보라색
Grep+While
[위 답변, grep 및 while 루프 참조]. While loop
- 노란색필요하지 않은 완전한 bash 솔루션grep
각 파일 크기와파편, 여러 번 반복,NR은 약자, 400부터 시작하여(더 짧은 파일의 경우)질소마지막 것은 100, 10, 1로 줄어듭니다.
그 값은 다음과 같이 기록됩니다.행당 시간,총인, 또한 ~으로 알려진실시간내장 기능으로 측정 time
및 평균화NR은 약자그리고질소. 둘 다 이후총인그리고질소10의 거듭제곱에 걸쳐 상용 로그(기본 10 또는 10의 거듭제곱)를 플로팅합니다. 보고된 선은 각 점을 접촉하는 베지어 곡선입니다.
더 큰 값의 경우질소이것행당 시간거의 일정해집니다. 이를 점근적 행동이라고 합니다. 예상대로 컴파일된 프로그램에서 사용하는 숫자가 낮을수록 결과가 더 빨라집니다.
반대로 작은 파일의 경우 결과는 반대입니다. 다양한 코드의 효율성은 (예를 들어) 40줄과 140줄 사이의 영역에서 교차합니다. 작은 파일이라 정말 작은 용량이지만, 전체적으로는인간의 시간사용하면 많은 수의 작은 파일을 처리해야 할 때 동일한 고려 사항이 더 이상 유지되지 않습니다. 순수 bash 코드(노란색)는 녹색 코드보다 점근적으로 8.12배 느리고157배 더 느리더라도빨간색 파일의 경우(11M 라인 파일의 경우 녹색의 경우 41.21초, 빨간색의 경우 2.16초 대신 334.56초를 사용함), 400회 반복 시간에 1.20초를 사용할 때 11M 라인 파일의 경우 각각 2.16배 및 1.58배 더 빠릅니다. 빨간색의 경우 1.89초, 녹색의 경우 2.59초가 아닙니다.
결론적으로: 많이 알수록 도전할 수 있다, 그리고 가능한지 확인해보세요! :-)
Ps> 비슷한 고려 사항은 다음에서도 찾을 수 있습니다.사용자 시간그리고시스템 시간, 그러나 교차 영역이 약간 다릅니다.
세게 때리다 4.3.11(1)-릴리스
반죽(GNU 코어유틸) 8.21
자르다 (GNU 코어유틸) 8.21
grep (GNU grep) 2.16
핵심3.13.0-24-일반 x86_64