Linux에서 정확히 두 개의 열이 있는 행 선택

Linux에서 정확히 두 개의 열이 있는 행 선택

파일 이름과 해당 성적표 사이의 맵인 파일이 있습니다. 파일 이름과 레코드는 탭으로 구분됩니다.

파일 기록에는 단일 공백으로 구분된 하나 이상의 단어가 포함될 수 있습니다. 다음은 파일의 레이아웃입니다.

[filename] [tab space] [trancription]

일부 행에서는 전사 열이 비어 있습니다. 이 줄은 다음과 같은 형식입니다.

[filename]

즉, 이 파일 이름에 사용할 수 있는 기록이 없습니다.

이제 내 임무는 파일 이름과 전사본(즉, 전사 열이 비어 있지 않은 파일)이 있는 행만 선택되었는지 확인하는 것입니다.

나는 다음 명령을 시도했다

(1) awk 'NF>2' filename

(2) awk 'NF==2' filename

(3) awk 'NF>1' filename

하지만 결과가 없어

또한 명령을 사용할 때

(4) awk ' NF==2 {print $0} '   myfile  > newfile

또한 "파일 이름" 필드라는 열이 하나만 있는 행도 가져옵니다.

쓸 때 NF<1출력이 없습니다(예상대로). NF<2다시 쓸 때 출력이 없습니다(이상합니다. 열이 하나만 있는 행이 표시되어야 합니다). 쓸 때 NF ==3정확히 두 개의 열이 있는 행이 표시됩니다(다시 혼란스럽습니다).

질문이 있으신가요? 정말 혼란스럽습니다.

이제 입력 샘플을 보내드립니다.

M07UP36A0821I40.wav 
M07UP36A0821I41.wav 
M07UP36A0821I410.wav    gaajara <bn>
M07UP36A0821I411.wav    tiina sau <pau> taintaaliisa
M07UP36A0821I412.wav    geehuun anya <bn>
M07UP36A0821I413.wav    geehuun daraa <babble>

이제 명령을 사용합니다.

grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' cll

명령은 출력을 제공하지 않았습니다(터미널이나 리디렉션된 파일 모두에서).

이제 주목해야 할 흥미로운 사항이 있습니다.

입력 파일에 다음이 포함된 경우

M07UP36A0822I413.wav    <bn> geehuun daraa <horn> <babble>
M07UP36A0822I414.wav    
M07UP36A0822I415.wav    gudxqa piilaa <horn> <babble>
M07UP36A0822I416.wav    <vn> gudxqa
M07UP36A0822I417.wav    gudxqa
M07UP36A0822I418.wav    gudxqa anya <babble>
M07UP36A0822I419.wav    harii matxara <bn> <babble>

다시, 동일한 명령을 사용하십시오

grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' foo

터미널에 출력이 표시되기 시작했습니다. 여기서 출력은 다음과 같습니다.

M07UP36A0822I417.wav    gudxqa

foo 파일에 대해 내가 원하는 출력은 완전한 행입니다(첫 번째 열과 두 번째 열이 모두 있어야 함). 이것이 원하는 출력입니다.

M07UP36A0822I413.wav    <bn> geehuun daraa <horn> <babble>
M07UP36A0822I415.wav    gudxqa piilaa <horn> <babble>
M07UP36A0822I416.wav    <vn> gudxqa
M07UP36A0822I417.wav    gudxqa
M07UP36A0822I418.wav    gudxqa anya <babble>
M07UP36A0822I419.wav    harii matxara <bn> <babble>

나는 clll 파일에서 다음 명령을 사용했습니다 (내 질문의 첫 번째 예)

awk -F'\t' '(NF !=2) { print "line: " NR " does not have 2 columns: " $0 ;}' cll

결과가 터미널에 표시됩니다. 밝혀지다

line: 1 does not have 2 columns: M07UP36A0821I40.wav 
line: 2 does not have 2 columns: M07UP36A0821I41.wav 
line: 3 does not have 2 columns: M07UP36A0821I410.wav    gaajara <bn>
line: 4 does not have 2 columns: M07UP36A0821I411.wav    tiina sau <pau> taintaaliisa
line: 5 does not have 2 columns: M07UP36A0821I412.wav    geehuun anya <bn>
line: 6 does not have 2 columns: M07UP36A0821I413.wav    geehuun daraa <babble>

답변1

사용 grep:

grep -E '^[^\s]+\s+[^\s]+$' file.txt
  • [^\s]+첫 번째 열, 공백 수 \s+, 마지막으로 두 번째(마지막) 열을 포함합니다.

  • ^줄의 시작을 나타내고 $줄의 끝을 나타냅니다.


POSIX 방식:

grep '^[^[:blank:]]\+[[:blank:]]\+[^[:blank:]]\+$' file.txt

답변2

다른 답변은 \s+오버매칭을 사용하세요! \s또한 데이터의 공백 발생과 일치합니다. 당신이 찾고 있는 것은 "Field_not_포함_TAB", "Tab", "Field_not_포함_TAB" 순입니다. 또는 정규식 용어로 말하면

egrep '^[^Tab]+Tab[^Tab]+$' file.txt

Space참고: 내 rexexp의 ' 사이에는 문자가 있어서는 안 됩니다 egrep. 표시 하기 위해 사용해야 했던 형식 지정 태그 때문에 kbd거기에서 볼 수 있습니다 .Tab

정규식은 제공된 데이터와 일치합니다(또는 options 를 사용하여 일치하지 않음) -v.egrep

답변3

여러분에게 두 개의 열은 뭔가[TAB]뭔가이고, 뭔가에 공백이 있을 수 있습니다. 따라서 필드 구분 기호가 탭이라고 awk에게 알려주십시오.

awk -F'\t' '(NF==2)'

또 누구인지 알아보세요:

awk -F'\t' '(NF !=2) { print "line: " NR " does not have 2 columns: " $0 ;}'

편집하다: 파일 구조에 대해 "오해의 소지가 있는" 것 같습니다. 파일에 1단어 또는 1단어, 탭 및 1개 이상의 단어(공백으로 구분)가 포함될 것이라고 말합니다. 그렇다면 위의 접근 방식이 효과적입니다. 그러나 파일에 대한 위 명령의 결과를 고려하면 단어 1개, [공백 또는 탭], 그리고 단어 [그리고 사이에 공백 또는 탭]이 있을 수 있습니다.

따라서 해결책은 다음과 같습니다.

awk -F'[\t ]+'  '(NF>=2)'    #words are separated by space&tabs, and we want at least 2 words [a filename, and its description]

변형: 두 번째 단어가 비어 있지 않은 줄을 출력합니다.

awk -F'[\t ]+'  '(length($2)>0)'    #words are separated by space&tabs, and we want athe 2nd word to be non empty
#or, one that also verifies the 1st word is non empty:
awk -F'[\t ]+'  '(length($1)>0 && length($2)>0)'    #1st and 2nd words are non-empty

관련 정보