제목을 최대한 구체적으로 만들려고 노력했습니다. 예를 들어야 합니다.
1
to 로 시작하는 줄이 있는 탭으로 구분된 파일이 있습니다 5
. 이는 블록으로 처리됩니다(각 블록은 여러 개의 4
항목을 가질 수 있음 5
).
- next는
1
다음 블록의 시작을 정의하는 식입니다. - 내 접두사는 항상 로 시작하는 줄에 있습니다
3
. 각 블록의 각 줄 시작 부분에 이 단어를 쓰고 싶습니다.
이 문제를 해결하는 방법에 대한 아이디어를 주시면 감사하겠습니다. 반드시 그런 것은 아니지만 sed
그럴 수도 있지만 awk
첫 sed
번째 선택이 될 것입니다.
- 입력 파일 예
1 foo1 2 foo1 3 bar1 | Prefix block 1 4 foo1 5 foo1 1 foo2 2 foo2 3 bar2 | Prefix block 2 4 foo2 4 foo3 5 foo2 5 foo3
- 이 입력 예에 대한 원하는 출력
bar1 1 foo1 bar1 2 foo1 bar1 3 bar1 bar1 4 foo1 bar1 5 foo1 bar2 1 foo2 bar2 2 foo2 bar2 3 bar2 bar2 4 foo2 bar2 4 foo3 bar2 5 foo2 bar2 5 foo3
답변1
귀하의 경우 awk
솔루션은 두 단계로 생각났습니다. 즉, 입력 파일 이름을 지정해야 함을 의미합니다.두 배명령줄의 피연산자로). 라인의 토큰은 입력 시 로 구분 \t
되고 출력 시로도 구분된다고 가정합니다 \t
.
awk 'BEGIN{FS=OFS="\t"}
NR==FNR{if ($1=="3") pre[++i]=$2;next} $1=="1" {j++} {print pre[j],$0}' input input
첫 번째 단계에서 NR
(전역 행 카운터)는 FNR
(파일별 행 카운터)와 동일하며 pre
첫 번째 필드( )가 동일한 행을 만날 때마다 $1
접두사 로 배열을 채웁니다 3
. 따라서 pre
"블록 번호"와 관련 접두사 간의 매핑입니다. 그 외에는 아무 것도 인쇄하지 않고 즉시 다음 실행 줄로 이동합니다.
두 번째 단계에서는 j
"시작 블록" 조건이 발견될 때마다(첫 번째 필드가 $1
) 1
블록 카운터를 증가시키고 모든 행에 대해 블록 카운터에 해당하는 접두사를 추가합니다.
답변2
GNU sed확장된 정규식 모드에서 실행 -E
하고 자동 인쇄를 꺼서 -n
인쇄 시기를 알 수 있습니다.
sed -En '
#--------------------------------
# printing the block in pattern space
#--------------------------------
/\n/{
s/.*\n(.*)/\1&/
P;/\n.*\n/D;$d;g
}
#--------------------------------
# collect block
#--------------------------------
:15
/^1/{
N;h
/\n5/!b15
#--------------------------------
# collect trailing 5 lines
#--------------------------------
:tail5
$bend
n
/^5/{H;$!btail5;}
#--------------------------------
# place block prefix @ eol
#--------------------------------
$!x;$g
:end
s/.*\n3\t([^\n]+)\n.*/\n&\n\1\t/
D; # take me to block print section
}
' file
결과:
bar1 1 foo1
bar1 2 foo1
bar1 3 bar1
bar1 4 foo1
bar1 5 foo1
bar2 1 foo2
bar2 2 foo2
bar2 3 bar2
bar2 4 foo2
bar2 4 foo3
bar2 5 foo2
bar2 5 foo3