awk 및 sed를 사용하여 공백 값을 이전 첫 번째 열 값으로 대체

awk 및 sed를 사용하여 공백 값을 이전 첫 번째 열 값으로 대체
john    math
        science
paul    math
        science
rosy    math
jill    science
rob     math
        science
hary    math

원하는 출력:

john    math
john    science
paul    math
paul    science
rosy    math
jill    science
rob     math
rob     science
hary    math

답변1

를 사용 awk하여 여러 필드에 작업을 수행합니다.

$ awk 'NF==1{print p "\t" $1; next} {p=$1} 1' ip.txt
john    math
john    science
paul    math
paul    science
rosy    math
jill    science
rob     math
rob     science
hary    math
  • {p=$1} 1단일 필드가 아닌 행의 경우 첫 번째 열을 저장하고 행을 인쇄합니다.
  • NF==1{print p "\t" $1; next}필드가 하나만 있는 경우 이전 필드 tab와 입력 줄의 필드를 인쇄합니다. next나머지 문을 건너뛰고 다음 줄을 처리합니다.


tab분리가 작동하지 않으면 다음을 사용하십시오 .column

$ awk 'NF==1{print p,$1; next} {p=$1} 1' ip.txt | column -t
john  math
john  science
paul  math
paul  science
rosy  math
jill  science
rob   math
rob   science
hary  math

답변2

다음과 같은 방법으로 할 수 있습니다 sed.

sed ':n; N; s/\n[^ ]/&/; tsplit; s/^\([^ ]* *\)\([^ ]*\n\) *\([^ ]*\)$/\1\2\1\3/; :split; h; s/\n.*$//; p; g; s/^.*\n//; bn' test.txt

설명하다

sed '# Start label for loop
:n
# Read next string to main buffer, separated by "\n"
N
# Split and print first string if second starts with non-space character
s/\n[^ ]/&/
tsplit
# "^\([^ ]* *\)" -- First word with spaces, \1.
# "\([^ ]*\n\)"  -- Second word, \2.
# " *"           -- Spaces in second line, throw them.
# "\([^ ]*\\)"   -- Second word in second line, \3.
s/^\([^ ]* *\)\([^ ]*\n\) *\([^ ]*\)$/\1\2\1\3/
# Splitting
:split
# Send both lines to hold buffer
h
# Delete second line, print first
s/\n.*$//
p
# Lines to main buffer, delete first.
g
s/^.*\n//
# Now second file is first, start loop again.
bn' test.txt

관련 정보