다음과 같은 입력 파일이 있습니다.
1001 Ivanov I.I: chess
2021 Petrov P.P: chess, football
3352 Sidorov S.S:
1000 Putin V.V: judo
8773 Schwarzenegger A: judo, chess, football
출력은 다음과 같을 것으로 예상됩니다.
-- chess --
Ivanov I.I
Petrov P.P
Schwarzenegger A
-- football --
Petrov P.P
Schwarzenegger A
-- judo --
Putin V.V.
Schwarzenegger A
답변1
이것은 질문에 지정한 대로 정확하게 작업을 수행하는 추악한 "oneliner"입니다.
for tag in `cat input |cut -d: -f2 |sed 's/<\/p>//g' |sed '/^[[:space:]]*$/d' |tr "," "\\n" | sed 's/[[:space:]]//g' | sort -u`; do echo "<p>-- $tag --</p>"; grep $tag input | awk '{print $2, $3}' | sed 's/://g' | sed 's/^/ <p>/' | sed 's/$/<\/p>/'; done;
그러나 나는 이 정확한 문제를 해결하는 데 도움을 주기 위해 이 글을 쓰는 것이 아닙니다. 저는 의도적으로 매우 구체적인 작업을 수행하는 부분으로 솔루션을 작성했으며 아래에는 이러한 부분이 수행하는 작업에 대한 설명이 나와 있습니다. 그러니 원한다면공부하다이 특정 문제를 해결하는 것 이상으로 이러한 도구를 사용하는 방법을 계속 읽어보세요!
비트별로 어떻게 작동하는지 살펴보겠습니다.
for tag in
- 라는 이름의 새 변수를 정의합니다 tag
. 이는 필요한 태그에 사용됩니다.
cat input
- 이름이 지정된 파일을 읽고 input
이 이름을 파일 이름으로 변경합니다.
|
파이프는 일련의 명령을 통해 데이터를 얻는 재미있는 방법입니다.
cut -d: -f2
- 콜론을 :
구분 기호로 사용하여 두 번째 필드를 가져옵니다. 그러면 각 줄의 콜론 뒤에 텍스트가 표시됩니다.
sed 's/<\/p>//g'
- 입력의 각 줄에서 닫는 단락 기호를 제거합니다.
이 시점에서 데이터는 다음과 같습니다.
chess
chess, football
judo
judo, chess, football
다음으로 공백으로만 구성된 빈 줄을 제거해 보겠습니다. 일부 줄에는 연결된 태그가 없기 때문입니다.
sed '/^[[:space:]]*$/d'
- 공백만 있는 모든 줄을 제거합니다. 엄청난!
tr "," "\\n"
- 각 라벨이 별도의 줄에 표시되도록 모든 쉼표를 개행 문자로 바꾸세요.
sed 's/[[:space:]]//g'
- 줄 시작 부분의 추가 공백을 제거합니다.
sort -u
- 태그를 알파벳순으로 정렬하고 중복된 태그를 제거합니다. 이제 우리는 중복 없이 순서대로 모든 태그의 완벽한 목록을 갖게 되었습니다.
chess
football
judo
지금,각각이러한 태그에 대해 다음을 차례로 수행합니다.
echo "<p>-- $tag --</p>"
- 지정된 대로 단락 html 태그, 두 개의 대시, 태그 이름, 두 개의 대시 및 닫는 단락 태그를 인쇄합니다.
grep $tag input
- 특정 태그가 있는 행 찾기
awk '{print $2, $3}'
- 정자체 이름 필드(성 + 이니셜)
sed 's/://g'
- awk가 약어의 일부로 간주하는 콜론을 제거합니다.
sed 's/^/ <p>/'
- 각 줄의 시작 부분에 단락 태그를 추가합니다.
sed 's/$/<\/p>/'
- 각 줄 끝에 닫는 단락 태그를 추가하세요.
done;
- 끝났어, 예!
결과는 다음과 같습니다.
$ for tag in `cat input |cut -d: -f2 |sed 's/<\/p>//g' |sed '/^[[:space:]]*$/d' |tr "," "\\n" | sed 's/[[:space:]]//g' | sort -u`; do echo "<p>-- $tag --</p>"; grep $tag input | awk '{print $2, $3}' | sed 's/://g' | sed 's/^/ <p>/' | sed 's/$/<\/p>/'; done;
<p>-- chess --</p>
<p>Ivanov I.I</p>
<p>Petrov P.P</p>
<p>Schwarzenegger A</p>
<p>-- football --</p>
<p>Petrov P.P</p>
<p>Schwarzenegger A</p>
<p>-- judo --</p>
<p>Putin V.V</p>
<p>Schwarzenegger A</p>
편집: 누군가 라벨이 입력의 일부가 아니라고 언급했습니다. 이렇게 하면 상황이 약간 단순화됩니다.
$ for tag in `cat input |cut -d: -f2 |sed '/^[[:space:]]*$/d' |tr "," "\\n" | sed 's/[[:space:]]//g' | sort -u`; do echo "--$tag --"; grep $tag input | awk '{print $2, $3}' | sed 's/://g'; done;
--chess --
Ivanov I.I
Petrov P.P
Schwarzenegger A
--football --
Petrov P.P
Schwarzenegger A
--judo --
Putin V.V
Schwarzenegger A
답변2
awk -F: '{
sub( "[ 0-9]+", "", $1 )
gsub( " +", "", $2 )
cz=split( $2,comp,"," )
for( c=1; c<=cz; c++ ) {
if( comp[c] ) {
if( ! allcomp[comp[c]] )
fifocomp[++fifoc] = comp[c]
allcomp[comp[c]] = allcomp[comp[c]] " " $1 "\n"
}
}
} END {
for( c=1; c<=fifoc; c++ ) {
print "-- " fifocomp[c] " --"
printf "%s", allcomp[fifocomp[c]]
}
}' file
산출:
-- chess --
Ivanov I.I
Petrov P.P
Schwarzenegger A
-- football --
Petrov P.P
Schwarzenegger A
-- judo --
Putin V.V
Schwarzenegger A