마지막 열을 분리하고 중간 열 주위에 따옴표를 추가하려면 awk/sed를 사용하시겠습니까?

마지막 열을 분리하고 중간 열 주위에 따옴표를 추가하려면 awk/sed를 사용하시겠습니까?

라는 파일이 있는데 test.txt약간 조작한 후에는 다음과 같습니다.

Metabolism
Global and overview maps
01100 Metabolic pathways (1689)
01110 Biosynthesis of secondary metabolites (677)
01120 Microbial metabolism in diverse environments (356)
01200 Carbon metabolism (44)
012111 Carbon metabolism (151) test: test test (44)

이제 마지막 열을 대괄호 안의 숫자로 구분하여 별도의 열로 만들고 싶습니다(선택한 구분 기호로 세미콜론 사용). 또한 괄호 안의 숫자와 시작 부분의 ID 번호 사이의 모든 텍스트 주위에 따옴표를 넣고 싶습니다. 마지막으로 헤더 행(이 경우 처음 두 행)을 유지하고 싶습니다.

내 코드:

 sed -r 's/ +/;/' test.txt | awk 'NF{NF-=1};1' | awk -F ";" '{sub($2, "\"&\""); print}'

내 현재 출력:

""
Global;"and overview"
01100;"Metabolic pathways"
01110;"Biosynthesis of secondary metabolites"
01120;"Microbial metabolism in diverse environments"
01200;"Carbon metabolism"
012111;Carbon (151) test: test test

보시다시피, "Metabolism" 헤더는 기술적으로 행의 마지막 값이고 두 번째 행의 "Map"이기 때문에 사라집니다. "Global" 뒤에는 필요하지 않은 세미콜론이 있습니다. 일부 행에는 텍스트에서 괄호 안에 숫자가 있는데 이를 그대로 유지해야 하지만 그렇지 않은 경우 모든 행은 괄호 안의 값으로 끝나며 이 값은 세미콜론으로 구분된 고유한 열로 구분되어야 합니다. 또한 마지막 행의 두 번째 열 전체에 따옴표를 붙일 수 없지만 다른 행은 괜찮습니다. 마지막으로 세 번째 열이 되도록 괄호 안의 값을 어떻게 구분해야 하는지 모르겠습니다.

내가 원하는 출력(숫자를 sep 열로 유지):

"Metabolism"
"Global and overview"
01100:"Metabolic pathways";1689
01110:"Biosynthesis of secondary metabolites";677
01120:"Microbial metabolism in diverse environments";356
01200:"Carbon metabolism";44
012111:"Carbon metabolism (151) test: test test";44

awk GNU 버전 4.1.3 및 sed GNU 버전 4.2.2를 사용하세요. Windows Linux 하위 시스템에서

답변1

$ cat file
Metabolism
Global and overview maps
01100 Metabolic pathways (1689)
01110 Biosynthesis of secondary metabolites (677)
01120 Microbial metabolism in diverse environments (356)
01200 Carbon metabolism (44)
012111 Carbon metabolism (151) test: test test (44)
$ sed -e 's/^\([[:digit:]]*\)[[:blank:]]*/\1;"/' -e 's/[[:blank:]]*\((\([[:digit:]]*\))\)\{0,1\}[[:blank:]]*$/";\2/' file
;"Metabolism";
;"Global and overview maps";
01100;"Metabolic pathways";1689
01110;"Biosynthesis of secondary metabolites";677
01120;"Microbial metabolism in diverse environments";356
01200;"Carbon metabolism";44
012111;"Carbon metabolism (151) test: test test";44

여기에 사용된 명령은 sed두 가지 대체를 수행합니다.

  • s/^\([[:digit:]]*\)[[:blank:]]*/\1;"/
    이는 줄 시작 부분의 빈 숫자 시퀀스를 대체하고 그 뒤에 0개 이상의 공백(탭 또는 공백)과 숫자 및 세미콜론이 옵니다. 줄 시작 부분에 숫자가 없으면 줄 시작 부분에 세미콜론이 삽입됩니다. 또한 세미콜론 뒤에 두 번째 필드의 첫 번째 큰따옴표 문자를 삽입합니다.

  • s/[[:blank:]]*\((\([[:digit:]]*\))\)\{0,1\}[[:blank:]]*$/";\2/
    이는 임의의 숫자 수, 주변 괄호 및 줄 끝의 초기 공백(해당 숫자 괄호가 있는 경우)과 일치합니다. 또한 줄 맨 끝에 추가 공백을 허용합니다. 일치하는 텍스트만 일치하는 숫자로 바꿉니다. 삽입된 숫자 앞에는 ;두 번째 필드의 두 번째 큰따옴표와 구분 기호가 옵니다 .

    당신은 원하십니까?제거하다마지막 필드의 숫자를 입력하고 sed두 번째 표현식의 대체 텍스트를 수정합니다(대신 ") ";\2.

sed명령

sed -e 's/^\([[:digit:]]*\)[[:blank:]]*/\1;"/' \
    -e 's/[[:blank:]]*\((\([[:digit:]]*\))\)\{0,1\}[[:blank:]]*$/";\2/' file

확장된 정규 표현식과 더 짧은 대괄호 표현식을 사용하여 다시 작성할 수 있습니다(탭이 아닌 공백만 일치시키려고 한다고 가정하는 경우).

sed -E \
    -e 's/^([0-9]*) */\1;"/' \
    -e 's/ *(\(([0-9]*)\))? *$/";\2/' file

답변2

GNU sed 사용:

sed -e '1,2{p;d}' -e 's/ /;"/' -e 's/ ([[:digit:]]\+)$/"/' input

이상 호환 가능:

sed -e '1{p;d;}' -e '2{p;d;}' -e 's/ /;"/' -e 's/ ([[:digit:]]\{1,\})$/"/' input

답변3

GNU sed확장 정규식 모드에서 사용하면 -E헤더 줄을 대괄호로 묶인 숫자로 끝나지 않는 줄로 식별합니다. 가정:

  • 선행/후행 공백이 없습니다.
  • 연속된 공백이 없습니다.
  • 입력에 Unix 줄 끝(\n)이 있습니다.
sed -Ee '
  /\s\(([0-9]+)\)$/!s/.*/;"&";/;t
  s//";\1/;s/\s/;"/
' file
;"Metabolism";
;"Global and overview maps";
01100;"Metabolic pathways";1689
01110;"Biosynthesis of secondary metabolites";677
01120;"Microbial metabolism in diverse environments";356

perl -lpe '
  s/\s\K\((\d+)\)$/$1/ ?
    s/\s(.*)\s/;"$1";/ :
    s/(.*)/;"$1";/     ;
' file

이를 사용하면 perl다음을 수행할 수 있습니다(위와 동일한 가정).

  • 처음 n개의 마지막 필드를 각각 스칼라 $a $b에 저장합니다(대괄호로 묶인 숫자로 끝나는 줄에 대해서만).
perl -slane 'local($a,$b);
  ($a,$b) = (shift(@F),pop(@F))
    if /\s\(\d+\)$/;
  print $a, qq("@F"), $b =~ tr/()//dr;
' -- -,=\; file

awk '
$NF ~ /^\([0-9]+)$/ &&
p = match($0,/ .* /) {
  l = length($NF)
  mid = substr($0, p, RLENGTH)
  gsub(/^ | $/, "\"", mid)
  print $1, mid, substr($NF, 2, l-2)
}
!p&&(sub(/.*/, ";\"&\";")||1)
' OFS=\; file

답변4

줄 끝의 "(숫자)"만 제거하려면 다음을 수행하세요.

sed 's|\(^.*\) ([[:digit:]]*)$|\1|g' test.txt

당신에게 줄 것입니다 :

Metabolism  # this header I need to keep
Global and overview maps  # this header I need to keep
01100 Metabolic pathways
01110 Biosynthesis of secondary metabolites
01120 Microbial metabolism in diverse environments

관련 정보