패턴을 기반으로 여러 줄을 결합하는 방법은 무엇입니까?

패턴을 기반으로 여러 줄을 결합하는 방법은 무엇입니까?

두 줄이 공유하는 패턴을 기반으로 파일의 여러 줄을 결합하고 싶습니다.

이것은 나의 예입니다:

{101}{}{Apples}
{102}{}{Eggs}
{103}{}{Beans}
{104}...
...

{1101}{}{This is a fruit.}
{1102}{}{These things are oval.}
{1103}{}{You have to roast them.}
{1104}...
...

나는 그 줄에 합류하고 싶다 {101}{}{Apples}.{1101}{}{This is a fruit.}

{101}{}{Apples}{1101}{}{This is a fruit.}추가 처리를 위해 한 줄로 .

다른 라인도 마찬가지다.

보시다시피 두 노선 모두 101번을 공유하지만 어떻게 해야 할지 모르겠습니다. 어떤 아이디어가 있나요?

/편집하다:

"해결 방법"을 찾았습니다.

먼저 (또는 유사한 단축키)를 사용하여 VISUAL BLOCK 모드의 그룹 2에서 앞의 "{1" 문자를 모두 삭제한 다음 를 사용하여 C-V모든 줄을 숫자별로 정렬한 다음 을 사용하여 :%sort n두 번째 줄마다 결합합니다 .:let @q = "Jj"500@q

이것은 작동하지만 {101}{}{Apples} 101}{}{This is a fruit.}. 그런 다음 각 줄에 누락된 문자 "{1"을 추가해야 합니다. 이는 제가 원하는 것과는 다릅니다. 도움을 주시면 감사하겠습니다.

답변1

을 삭제하는 대신 {1다음을 수행하십시오.

:%sort rn /\d\d\d}/

그러면 숫자 정렬이 수행되지만 각 줄에서는 세 자리 숫자 뒤에 }만 표시됩니다.

그리고 나중에 줄에 합류하려면

:g/{\d\d\d}/j!

답변2

파일을 사용하여 셸에서 이를 수행하는 방법은 다음과 같습니다.

join -j 2 \
    <(sed -n '/^{...}/{s/{/{ /;s/}/ }/;p}' inputfile) \
    <(sed -n '/^{....}/{s/{./& /;s/}/ }/;p}' inputfile) |
    sed 's/^\([^ ]*\) { }{}\({[^}]*}\) {1 }\({.*}\)$/{\1}{}\2{1\1}\3/'

의 처음 두 호출을 사용하여 sed첫 번째 중괄호 세트 사이의 자릿수를 기준으로 파일을 분할하고 마지막 세 자릿수 주위에 공백을 추가합니다( {101}goes { 101 }{1101}goes {1 101 }). 그런 다음 이 세 자리 숫자를 명령 키의 필드로 사용합니다 join. 마지막 sed명령은 숫자를 원래 위치로 되돌리고 이전에 추가한 추가 공백을 제거합니다.

전문가 vim는 아마도 내에서 더 나은 일을 할 수 있을 것입니다 vim. AWK를 사용하면 위의 것보다 더 간단한 작업을 수행할 수 있습니다.

답변3

다음은 하나의 패턴에 대해 명령줄에서 Vim/Ex 편집기를 사용하는 예입니다.

$ ex +'redir @a|sil g/101}/' +'redi>>/dev/stdout|echon join(split(@a),"")' -scq! input.txt 
{101}{}{Apples}{1101}{}{This is a fruit.}

여러 패턴의 경우 추가 명령을 사용하여 반복하거나, 루프를 추가하거나, 셸에서 반복합니다. 예:

$ for i in `seq 1 3`; do ex +"redir @a|sil g/10$i}/" +'redi>>/dev/stdout|echo join(split(@a),"")' -scq! input.txt; done
{101}{}{Apples}{1101}{}{Thisisafruit.}
{102}{}{Eggs}{1102}{}{Thesethingsareoval.}
{103}{}{Beans}{1103}{}{Youhavetoroastthem.}

쉘을 사용하여 데이터를 구문 분석하면 훨씬 간단합니다. 예:

$ grep "101}" input.txt | xargs
{101}{}{Apples} {1101}{}{This is a fruit.}

여러 줄의 경우:

$ for i in `seq 1 4`; do grep "10$i}" input.txt | xargs; done
{101}{}{Apples} {1101}{}{This is a fruit.}
{102}{}{Eggs} {1102}{}{These things are oval.}
{103}{}{Beans} {1103}{}{You have to roast them.}

관련 정보