sed, awk, perl 또는 vim을 사용하여 텍스트 블록 교체

sed, awk, perl 또는 vim을 사용하여 텍스트 블록 교체

6행 블록의 각 인스턴스를 다른 6행 블록으로 교체하려고 합니다. 6행 블록의 두 열을 6행 블록의 한 열로 줄이기만 하면 됩니다.

귀하의 의견에 감사드립니다. 이 질문을 더 명확하게 작성하겠습니다. 나는 여러 개의 기타 탭 텍스트 파일을 가지고 있는데 각각에는 많은 음악 "라인"이 포함되어 있습니다. 음악의 각 "라인"에는 6개의(같은 수의 기타 줄) 연속된 텍스트 라인이 있습니다. 음악의 "줄" 사이에는 빈 줄(또는 텍스트 포함)이 있습니다. 일반적으로 이 6개의 "라인"은 길이가 약 200열이며, 6개의 수직 행을 6개의 수직 행으로 대체하여 행의 길이를 줄이고 싶습니다.

예를 들어. 첫 번째 블록을 두 번째 블록으로 줄이고 싶습니다.

|------------------|    |-------|            
|------------------|    |-------|    
|-0----------------|    |-0-----|   
|-2-----2-----2----|    |-2-2-2-|     
|-------2----------|    |---2---|       
|-------------0----|    |-----0-| 

다음 코드를 시도했습니다(unix.stackexchange 참조).1) 성공하지 못했습니다:

sed -i '/--/,/--/,/--/,/--/,/--/,/--/c\
-\
-\
-\
-\
-\
-' a.txt

awk, vim 또는 perl을 사용하여 더 나은 결과를 얻지 못했습니다.

예를 들어 awk 및 필드 구분 기호 empy를 사용하는 부분적인 솔루션은 문자가 모두 null 또는 "-"인 두 개의 연속 열을 찾는 것입니다. 그런 다음 두 열 중 하나를 삭제합니다. 하지만 어떻게 해야할지 모르겠습니다.

답변1

귀하가 게시한 태블러추어는 6자리 길이의 곡인 을 기반으로 한 것 같습니다. -x----여기서 x프렛 번호 또는 대시는 다음과 같습니다. 이와 같이:

 123456123456123456
 -x-----x-----x----
|------------------|
|------------------|
|-0----------------|
|-2-----2-----2----|
|-------2----------|
|-------------0----|

그렇다면모두이 간격을 사용하면 다른 줄을 생각할 필요 없이 조각을 변경하여 일부 대시를 제거할 수 있습니다.

$ sed -Ee 's/-(.)----/-\1/g; s/\|/-|/2' < tab
|-------| 
|-------|
|-0-----|
|-2-2-2-|
|---2---|
|-----0-|

그러나 동일한 파일에 서로 다른 간격으로 탭을 작성하면 각 탭의 간격을 식별해야 하기 때문에 더 어려워지며 일반적으로 첫 번째 줄에서도 이를 수행할 수 없습니다. (귀하의 예와 같이 비어 있을 수 있기 때문입니다.)

보다 일반적인 경우에 제가 제안할 수 있는 해결책은 전체 악보를 디코딩한 다음 이를 다시 인쇄하는 것인데, 이는 이 답변에는 적합하지 않습니다.


sed의 /this/,/that/구문은 첫 번째 줄이 일치하는 줄 블록을 처리합니다 /this/.마지막행이 일치 /that/하고 블록에 다음이 포함됩니다.모두사이의 선. /--/,/--/,/--/,...따라서 블록의 시작과 끝보다 더 많은 패턴이 있으므로 이것은 말도 안되는 일입니다.

태블러추어처럼 보이는 블록을 일치시키려면 일치시킨 |-다음 블록이 6줄을 확장하도록 해야 합니다. GNU sed에서는 이것을 사용할 수 있습니다 /^|-/,+6.

답변2

vim에서는 시각적 차단 모드를 사용하여 삭제하려는 열을 강조 표시합니다.

<C-v>

좋아하는 이동 명령( 실수할 경우 조정할 수 있도록 블록 모서리로 점프) o도 포함됩니다 .O

그런 다음 를 입력합니다 d.

답변3

나는 다음 방법으로 그것을했다

주문하다

i=`awk '{print NR}' l.txt | sort -nr | sed -n '1p'`

 for ((j=1;j<=$i;j++)); do sed -n ''$j'p' filename|awk -F "" '{gsub("","\n",$0);print $0}'|sort | uniq;done| sed '/^$/d'| sed "N;s/\n/ /g"| awk '{print $NF,$1}'| sed -r "s/ //g"

산출

x\
x\
x\
x\
x\
x\

관련 정보