질문

질문

질문

다음 형식의 32M 라인 파일이 있습니다

token^Iname^Iurl$

어디에^I상표이스케이프 시퀀스 $이며줄 끝.

url이 필드에 대해 10,000개 이하의 일치 ​​항목을 얻어야 합니다 name. 내가 한 일은

# Get second column
cut -f2 <myFile> |
# Find the word and line number
grep -nwi "<matchWord>" |
# Get just the number
cut -f1 -d ':' |
# Not more than 10k
head -n10000

그런 다음 이전 출력의 각 항목에 대해

# Print line number 
sed -n '<number>{p;q}' <myFile>
# Get 3rd field
cut -f3

이제 마지막 작업은 sed엄청나게 느립니다. grep처음 1,000개 게임을 한 후에도 속도가 느려지지 않는 방법만 사용하거나 다른 방법을 사용하여 이 모든 것을 얻는 방법을 알고 싶습니다 .

아이디어

grepcut -f2전체 행(아무것도 없음 )에서 두 번째 열에 대해서만 수행할 수 있다면 완벽할 것입니다 cut -f3. 하지만 어떻게 해야 할지 모르겠습니다.

라인 xyz

qwertyuiop^Ibananas are yellow^Ihttp://mignons.cool$

단어 일치노란색현장에서 name-> 주세요 http://mignons.cool.

cut라이브 콘텐츠 tokenurl.

grep으로 보내면 cut내가 관심 있는 필드 myFile에 더 이상 접근할 수 없습니다 .url

입력 및 예상 출력

입력 파일:

mxp4EdOy-IXkuwsuOfs0EQ^Ilegal yellow pad paper^I0/3/3031.jpg$
AeS7tgmlVffBhousr9YY5Q^Ihelicopter parking only sign^I0/3/3032.jpg$
8dl-VixSjG4Y0FpX9f5KHA^Iwritten list ^I0/3/3033.jpg$
XYvKZC3D_JSwlY8SPl-zLQ^Ihelicopter parking only road sign^I0/3/3034.jpg$
xF6zpvpHcmfpHP2MmT2FVg^Irun menu windows programming^I0/3/3035.jpg$
mCJvV2rXOmItLBkMZlyIwQ^Icoffee mug^I0/3/3040.jpg$
ZiobHk_dLsN-Q921KPJUTA^Icarpet^I0/3/3197.jpg$
xFrbGOMfVMl0WeqVAcT27A^Iwater jugs^I0/3/3199.jpg$

어디에^I상표이스케이프 시퀀스 $이며줄 끝.

단어를 일치시킵니다 helicopter.

예상 출력(10,000줄 이하):

0/3/3032.jpg
0/3/3034.jpg

잠재적인 솔루션

필드에는 url숫자만 포함되어 있으므로 다음을 수행할 수 있습니다.

cut -f 2,3 <myFile> | grep <matchWord> | cut -f2 | head -n10000

grep하지만 2번 필드에만 가는 게 나을 것 같은데...

답변1

이를 수행하는 방법에는 여러 가지가 있습니다. 가장 간단한 것은 아마도awk

$ awk -F$'\t' '$2 = /helicopter/ {print $3}' input.txt | head -n 10000
0/3/3032.jpg
0/3/3034.jpg
  • -F$'\t'필드 구분 기호를 TAB으로 설정
  • $2 = /helicopter/필드 2에서만 일치
  • print $3일치하는 항목에 필드 3을 인쇄합니다.

대소문자를 구분하지 않고 전체 단어를 일치시키려면 다음을 시도하십시오.

awk -F$'\t' 'tolower($2) ~ /\<helicopter\>/ { print $3}' input.txt | head -n 10000

및 (단어 경계 표시)만 작동할 수 있습니다. Linux를 사용하는 경우 이는 표준입니다 \<. 또한 비교 연산자가 에서 변경되었습니다.\>gawk=~

답변2

LC_ALL=C사용자 환경에서 로컬로 설정해 볼 수도 있습니다 .

LC_ALLUTF8 로케일인 경우 grep이 일치하기 전에 입력 스트림을 UTF8로 디코딩해야 하므로 작업 속도가 크게 느려질 수 있음을 의미할 수 있습니다 .grep

답변3

아마도 잘라내려고 해서는 안 될 것입니다 cut. 실제로 32M 입력 라인을 처리하기 위해 파이프라인을 단일 프로세스로 결합하려고 하면 작업의 전체 완료 시간에 부정적인 영향을 미칠 가능성이 높습니다. 그러나 이는 작업을 실행하는 컴퓨터 유형에 따라 다릅니다.

데이터를 처리하는 기계에 여러 프로세서 코어가 있는 경우 일반적으로 작업 루프를 단일 프로세스로 통합한다는 것은 전체 작업을 단일 프로세서 코어에 통합한다는 의미입니다. 이는 프로세서 코어가 하나만 있는 시스템이나 전체 CPU 시간이 중요한 경우에 이상적일 수 있지만 내 경험상 프로세서를 포화시키고 모든 코어를 동시에 사용하여 작업을 더 빠르게 완료하는 것이 더 좋습니다.

즉, grep두 번째 필드만 사용해도 됩니다.

grep -E $'\t(.* )?yellow( .*)?\t' <infile

...이 패턴은 한 줄의 두 탭 문자 사이에 있는 문자열과만 일치하며 양쪽이 공백이나 필드 구분 탭 문자로 구분된 문자열과만 일치합니다. GNU를 사용하면 ax match 스위치를 grep추가하여 -m출력을 10K 이하로 제한할 수도 있습니다. 그래서...

grep -m10000 -E $'\t(.* )?yellow( .*)?\t' <infile | cut -f3

...전체 작업을 완료하기에 충분합니다.

관련 정보