programing

다중 행 문자열에서 지정한 열을 쉼표로 구분된 단일 행으로 변환

muds 2023. 5. 11. 21:59
반응형

다중 행 문자열에서 지정한 열을 쉼표로 구분된 단일 행으로 변환

다음과 같은 문자열이 있다고 가정합니다.

something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

어떻게 하면 그것을 단순하게 만들 수 있습니까?

+12.0,+15.5,+9.0,+13.5

바쉬에서?

깔끔하고 단순함:

awk '{print $2}' file.txt | paste -s -d, -

사용할 수 있습니다.awk그리고.sed:

awk -vORS=, '{ print $2 }' file.txt | sed 's/,$/\n/'

또는 파이프를 사용하려는 경우:

echo "data" | awk -vORS=, '{ print $2 }' | sed 's/,$/\n/'

분해 방법:

  • awk필드로 분류된 데이터를 처리하는 데 탁월합니다.
  • -vORS=,"출력 레코드 구분 기호"를 "로 설정합니다.,그게 당신이 원했던 것입니다.
  • { print $2 }말한다awk모든 레코드(라인)에 대해 두 번째 필드를 인쇄합니다.
  • file.txt파일 이름입니다.
  • sed그냥 추적을 제거합니다.,그리고 그것을 새로운 라인으로 바꿀 수 있습니다. (만약 당신이 새로운 라인을 원하지 않는다면, 당신은 할 수 있습니다.s/,$//)
cat data.txt | xargs | sed -e 's/ /, /g'

다음과 같은 이점이 있습니다.

cut -d' ' -f5 file | paste -d',' -s
+12.0,+15.5,+9.0,+13.5

또는

sed '/^.*\(+[^ ]*\).*/{s//\1/;H};${x;s/\n/,/g;s/.//p};d' file
+12.0,+15.5,+9.0,+13.5

또는

sed 's/\S\+\s\+//;s/\s.*//;H;$!d;x;s/.//;s/\n/,/g' file

파일의 각 줄에 대해 첫 번째 필드와 뒤에 오는 공백을 잘라내고 두 번째 필드에 이어지는 줄의 나머지 부분을 잘라낸 다음 홀드 공간에 추가합니다.홀드 공간으로 스왑한 마지막 라인을 제외한 모든 라인을 삭제하고 시작할 때 소개된 새 라인을 삭제한 후 모든 새 라인을 다음으로 변환합니다.,

N.B. 작성 가능:

sed 's/\S\+\s\+//;s/\s.*//;1h;1!H;$!d;x;s/\n/,/g' file
$ awk -v ORS=, '{print $2}' data.txt | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

$ cat data.txt | tr -s ' ' | cut -d ' ' -f 2 | tr '\n' ',' | sed 's/,$//'
+12.0,+15.5,+9.0,+13.5

어색한 원 라이너

$ awk '{printf (NR>1?",":"") $2}' file

+12.0,+15.5,+9.0,+13.5

이것도 효과가 있을 겁니다.

awk '{print $2}' file | sed ':a;{N;s/\n/,/};ba'

사용할 수 있습니다.grep:

grep -o "+\S\+" in.txt | tr '\n' ','

다음으로 시작하는 문자열을 찾습니다.+임의의 문자열 뒤에 오는 경우\S\+그런 다음 새 줄 문자를 쉼표로 변환합니다.대용량 파일의 경우 이 작업이 상당히 빠를 것입니다.

이 쉬운 코드를 사용해 보십시오.

awk '{printf("%s,",$2)}' File1

사용해 보십시오.

sedSelectNumbers='s".* \(+[0-9]*[.][0-9]*\) .*"\1,"'
sedClearLastComma='s"\(.*\),$"\1"'
cat file.txt |sed "$sedSelectNumbers" |tr -d "\n" |sed "$sedClearLastComma"

좋은 점은 새 줄 "\n"자를 삭제하는 쉬운 부분입니다!

편집: sed를 사용하여 줄을 하나의 줄로 결합하는 또 다른 좋은 방법은 다음과 같습니다.|sed ':a;N;$!ba;s/\n/ /g'여기서 왔습니다.

순수한 Bash로 작성된 솔루션:

#!/bin/bash

sometext="something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)"

a=()
while read -r a1 a2 a3; do
    # we can add some code here to check valid values or modify them
    a+=("${a2}")
done <<< "${sometext}"
# between parenthesis to modify IFS for the current statement only
(IFS=',' ; printf '%s: %s\n' "Result" "${a[*]}")

결과: +12.0, +15.5, +9.0, +13.5

이 간단한 해결책을 어색하게 보지 마세요.

awk 'b{b=b","}{b=b$2}END{print b}' infile

Perl 사용 시:

fg@erwin ~ $ perl -ne 'push @l, (split(/\s+/))[1]; END { print join(",", @l) . "\n" }' <<EOF
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
EOF

+12.0,+15.5,+9.0,+13.5

두 개의 SED 호출로도 이 작업을 수행할 수 있습니다.

$ cat file.txt 
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)
$ sed 's/^[^:]*: *\([+0-9.]\+\) .*/\1/' file.txt | sed -e :a -e '$!N; s/\n/,/; ta'
+12.0,+15.5,+9.0,+13.5

첫 번째 sed 호출은 관심 없는 데이터를 제거하고 두 번째는 모든 회선에 가입합니다.

다음과 같이 인쇄할 수도 있습니다.

그냥 어색해요: printf를 사용합니다.

bash-3.2$ cat sample.log
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

bash-3.2$ awk ' { if($2 != "") { if(NR==1) { printf $2 } else { printf "," $2 } } }' sample.log
+12.0,+15.5,+9.0,+13.5

Dan Fego의 awk와 유사한 또 다른 Perl 솔루션:

perl -ane 'print "$F[1],"' file.txt | sed 's/,$/\n/'

-aPerl에서 입력 라인을 @F 배열로 분할하도록 지시합니다. 이 배열은 0부터 시작하여 인덱스됩니다.

아마도 가장 어려운 부분은 두 번째 "열"을 선택하는 것입니다. 여러 공간을 하나로 취급하는 쉬운 방법을 모르기 때문입니다.나머지는 쉽습니다.bash 대체를 사용합니다.

# cat bla.txt
something1:    +12.0   (some unnecessary trailing data (this must go))
something2:    +15.5   (some more unnecessary trailing data)
something4:    +9.0   (some other unnecessary data)
something1:    +13.5  (blah blah blah)

# cat bla.sh
OLDIFS=$IFS
IFS=$'\n'
for i in $(cat bla.txt); do
  i=$(echo "$i" | awk '{print $2}')
  u="${u:+$u, }$i"
done
IFS=$OLDIFS
echo "$u"

# bash ./bla.sh
+12.0, +15.5, +9.0, +13.5

또 다른 AWK 솔루션

달려.

awk '{printf "%s", $c; while(getline){printf "%s%s", sep, $c}}' c=2 sep=','

두 번째 열을 사용하여 쉼표로 구분된 목록을 구성합니다.표준 입력 또는 파일 이름 인수로 평소와 같이 입력합니다.

언급URL : https://stackoverflow.com/questions/8714355/convert-specified-column-in-a-multi-line-string-into-single-comma-separated-line

반응형