쿼리에 다음 테이블이 있지만 +
구분 기호는 아래 예와 같이 "설명" 아래에 새 행을 만드는 것입니다.
TYPE+DESCRIPTION+PRIORITY+DATE
1+text1+HIGH+Aug 15
+text2
2+text+LOW+Aug 11
3+text+LOW+Aug 11
4+text1+HIGH+Aug 15
+text2
+text3
sed를 사용하여 다음과 같이 보이게 하려면 어떻게 해야 하나요?
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text text2 text3 HIGH Aug 15
나는 시도했다:
sed -n '1{h;n};/^ *+ */{s// /;H;n};{x;s/\n//g;p};${x;p}'
하지만 오류가 발생했습니다(sed: 명령이 깨졌습니다). 감사합니다.
답변1
awk '
BEGIN{OFS=FS="+"}
{sub(/[[:blank:]]+$/,"")} #Removes trailing blanks
NF==4{print line;line=$0}
NF==2{x=$2;$0=line;$2=$2" "x;line=$0}
END{print line}
' file | column -ts "+"
그 뒤에 있는 주요 아이디어는 if 가 NF==2
두 번째 필드를 $2
이전 행의 두 번째 필드에 넣는 것입니다. 그래서 무슨 일이 일어나는가?
1+text1+HIGH+Aug 15 #Puts this in "line" variable
+text2 #Transfer 2nd field to "line" second field
# Resulting in...
1+text1 text2+High+Aug 15
column
+
이 미세한 최종 출력을 생성하기 위해 출력에서 제거되었습니다.
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text1 text2 text3 HIGH Aug 15
답변2
"도메인 불가지론" 만들기awk
tac file | awk 'BEGIN{FS="+"}
{flds=(NF>flds)?NF:flds;for (i=1; i<=NF; i++) {f=(length($i)>0)?gensub(/ +$/,"","g",$i)" ":"";fld[i]=f fld[i]}}
$1>0{for (i=1; i<=flds; i++) printf fld[i]"+"; printf "\n"; delete fld}' |
tac | column -ts "+"
TYPE DESCRIPTION PRIORITY DATE
1 text1 text2 HIGH Aug 15
2 text LOW Aug 11
3 text LOW Aug 11
4 text1 text2 text3 HIGH Aug 15
송곳
$1이 비어 있지 않고 설정되었을 때 인쇄할 시간임을 알 수 있도록 파일을 뒤집습니다.FS
tac file | awk 'BEGIN{FS="+"}
최대 수를 계산하고 flds
, 필드를 반복하고, 잘라내고 공백을 확인하고, 필드별로 배열에 로드하여 집계합니다.
{flds=(NF>flds)?NF:flds;for (i=1; i<=NF; i++) {f=(length($i)>0)?gensub(/ +$/,"","g",$i)" ":"";fld[i]=f fld[i]}}
비어 있지 않으면 $1
라인을 출력하고 배열을 재설정합니다.
$1>0{for (i=1; i<=flds; i++) printf fld[i]"+"; printf "\n"; delete fld}' |
파이프를 통해 tac
뒤집어서 column
아름답게 만드는 데 사용하세요.
tac | column -ts "+"
편집하다
두 번째 루프가 정말 마음에 들지 않으며, 파이프에 있는 망치로 칠 gensub
수 있을 때 각 필드에서 중지하고 테스트를 단순화합니다. sed
우아한 느낌은 아니네요.
그래서 여기에골프를 치다버전은 그냥느끼다나에게 더 나은:
tac file | awk 'BEGIN{FS="+"}
{flds=(NF>flds)?NF:flds;
for (i=1; i<=NF; i++) {fld[i]=$i" "fld[i];
if ($1) printf fld[i]"+"}}
$1{ printf "\n"; delete fld}' |
sed -E "s/ +/ /g" | tac | column -ts "+"
답변3
돌아가서 sed 버전 간의 가능한 차이점을 읽고 처음부터 다시 작성하세요. 이것이 효과가 있기를 바랍니다:
:r
$!N
y:+:,:
/\n,/{
s:^\([^,]\{1,\},[^,]\{1,\}\)\([^\n]\{1,\}\)\n,\([^ \n]\{1,\}\).*$:\1 \3\2:
br
}
$!P
$!D
산출:
TYPE,DESCRIPTION,PRIORITY,DATE
1,text1 text2,HIGH,Aug 15
2,text,LOW,Aug 11
3,text,LOW,Aug 11
4,text1 text2 text3,HIGH,Aug 15
답변4
perl -0pe 'while(s/(.*?)\+(.*?)\+(.*)\n\+(.*)/$1+$2 $4+$3/g){}' file
perl -0
- 모든 입력을 삼키다s/(.*?)\+(.*?)\+(.*)\n\+(.*)/$1+$2 $4+$3/g
A+B+...C\n+D
가능하다면 전환을 하십시오A+B D+...C
.