이 ASCII 파일에서 이러한 줄을 분류하는 방법

이 ASCII 파일에서 이러한 줄을 분류하는 방법

내 ASCII 파일은 다음과 같습니다.

a
1 2 3
1223
b
1 2 3 5
3344
1223
c
1 2 34
a
4 5
c
123

a, b, c 아래의 행을 각각 수집하는 방법은 무엇입니까?

묻다:다음 줄을 얻으려면 어떻게 해야 합니까?

a
1 2 3
1223
4 5

답변1

awk '/^[a-z]$/ { f = $1=="a" ; if (!c++) print ; next }; f'

답변2

아, awk지금까지 본 다른 솔루션과 달리 하나의 데이터 전달만 사용하므로 작업이 훨씬 쉬워집니다.

/^[a-z]/{key=$0;} 
/^[0-9]/{if (key in res){ res[key]=res[key] "\n" $0;} else {res[key]=$0;}} 
END {for(key in res){
    print key; 
    print res[key];
    }}

sed+프릴만 원한다면 다음과 같이 작동하는 것 같습니다.

 cat data.txt | sed -e '/^a/,/^[b-z]/!d' | sed -e '2,${ /^[a-z]/d }'

(예, 이것은고양이의 쓸모없는 사용 교육학적 이유 때문에, 즉 파일이 파이프라인 중간 어딘가에 있으면 혼란스러워집니다. )

첫 번째는 sed문자(포함)로 시작하는 줄로 시작하고 끝나는 모든 범위를 고려합니다. 범위()를 무효화한 다음 일치하는 모든 항목을 제거하므로 다음과 같이 남습니다.ab-z!

a
1 2 3
1223
b
a
4 5
c

두 번째는 sed헤더를 유지하기 위해 라인 2부터 파일 끝까지의 범위만 살펴보고 a거기에서 문자로 시작하는 모든 라인을 제거 a-z하고 숫자 라인만 남깁니다.

a
1 2 3
1223
4 5

모든 제목의 목록을 얻으려면 시도해 볼 것입니다 grep '^[a-z]' | sort -u. 따라서 전체 짐승은 다음과 같습니다.

for key in $(grep  '^[a-z]' data.txt | sort -u ); do 
    cat data.txt | sed -e "/^$key/,/^[b-z]/\!d" | sed -e '2,${ /^[a-z]/d }'  ; 
done

답변3

awk '
/^[a-z]$/{
  i=$0
  next
  }
{
  A[i]=A[i] "\n" $0
  }
END{
  for (j in A)
    print j A[j]
  }'

보시다시피 이는 다음의 단순화된 변형입니다.@Ulrich Schwarz 스크립트: 소문자 하나만 포함된 줄의 경우 이 문자를 색인으로 사용 i하고 새 줄 루프를 시작합니다. 다음으로, 스크립트의 이전 부분에서 ewline 구분 기호를 사용하여 결정된 인덱스를 A기반으로 나머지 모든 줄(이전에 조작되었기 때문에 "단지 1개의 소문자"가 아님)을 연관 배열에 배치합니다 . 스크립트가 모든 행(도달)을 전달하면 배열이 인덱스로 인쇄됩니다.i\nENDAi

답변4

awk두 번째 인쇄를 방지하는 방법은 다음 과 같습니다 a.

awk '$1 == "a" { if (!head) print; n=head=1; next } $1 !~ /^[0-9]/ { n=0 } n' ascii_file

이러한 결과를 얻으려면 다음 "a"으로 바꾸십시오 ."b"

산출:

a
1 2 3
1223
4 5

루프를 원하면 다음과 같이 할 수 있습니다.

for letter in a b c; do
  echo
  awk -v letter="$letter" '$1 == letter { if (!head) print; n=head=1; next } $1 !~ /^[0-9]/ { n=0 } n' /tmp/a
done

다음과 같이 출력됩니다.

a
1 2 3
1223
4 5

b
1 2 3 5
3344
1223

c
1 2 34
123

(이 echo줄에 주목하세요. 각 쿼리에 대한 조회수를 구분합니다. 이 답변을 작성하여 알파벳순으로 쿼리할 수 있도록 했습니다. 이것이 바로 질문에 대한 이해입니다.)

관련 정보