일련의 문자(숫자)를 공백으로 구분하는 방법

일련의 문자(숫자)를 공백으로 구분하는 방법

나는 다음과 같은 상황에 처해 있습니다.

my data:

ID01 120120101
ID02 101010101
ID03 210210210
ID04 505052120

내가 원하는 데이터는 다음과 같습니다.output

ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

그래서 두 번째 열에 나타나는 모든 숫자를 분리하고 싶습니다(내 데이터), 그러나 첫 번째 열은 그대로 유지되어야 합니다.

이를 위해 두 개의 파일을 생성해 보았습니다. 하나는 ID($1-file1)이고 다른 하나는 공백으로 구분된 시퀀스(file2)입니다. 시도한 후:

sed -i -- 's//\t/g' file2

하지만 다음과 같은 오류가 발생합니다.

sed: -e expression #1, char 0: no previous regular expression

이 문제를 어떻게 해결할 수 있나요?

답변1

어때요?

perl -alne 'print join " ", $F[0], split("", $F[1])' data
ID01 1 2 0 1 2 0 1 0 1
ID02 1 0 1 0 1 0 1 0 1
ID03 2 1 0 2 1 0 2 1 0
ID04 5 0 5 0 5 2 1 2 0

(완전히) 탭으로 구분된 출력을 원하면 다음으로 변경하십시오.

perl -alne 'print join "\t", $F[0], split("", $F[1])' data

또는 ID두 번째 필드의 숫자 뒤에 탭을 유지하되 공백으로 구분하려면,

perl -alne 'print join "\t", $F[0], join " ", split("", $F[1])' data

답변2

에서 sed빈 정규식은 이전 정규식을 재사용하는 것을 의미하며, 이 경우에는 이전 정규식이 없습니다. 열을 분리하면 다음을 수행할 수 있습니다.

sed 's/./& /g' file2

(아무 문자나 일치시킨 다음, 일치하는 문자로 다시 바꾸고 &공백을 추가하세요.)

하지만 두 번째 열만 변경하는 것이 더 쉽습니다 awk.

awk '{gsub(/./, "& ", $2)} 1' data 

gsubsed 와 거의 동일합니다 s///g. 내가 테스트한 한, awk빈 정규식은 실제로 지원되지만 첫 번째 숫자 이전에도 일치하므로 추가 공간이 추가됩니다. (음, 위의 내용은 끝에 추가 공간을 추가합니다.)

답변3

예쁘지는 않지만 작동합니다

cat my_data | sed -e 's/./ &/g' -e 's/^ \(.\) \(.\) \(.\) \(.\)  /\1\2\3\4/'

첫 번째 표현은 모든 문자 앞에 공백을 넣습니다. 다음으로 첫 번째 부분의 공백을 제거합니다.

스크립트를 작성할 수도 있습니다.

#! /bin/bash
while read ID NUMBERS; do
    echo $ID$(echo $NUMBERS | sed -e 's/./ &/g')
done

그런 다음 실행

cat my_data | ./my_script

답변4

s플래그와 함께 명령을 사용할 수 없는 경우 한 가지 방법은 해당 명령과 함께 루프에서 이를 사용하는 것입니다 g(후속 조건에 따른 점프 조건).sts

여기:

sed -e :1 -e 's/\([^ ]\)\([^ ]\{1,\}\)$/\1 \2/;t1'

즉, 줄 끝의 공백이 아닌 것을 해당 공백, 공백 및 공백이 아닌 시퀀스로 바꾸고 그 뒤에 공백이 아닌 1개 이상의 시퀀스가 ​​뒤따르는 다음 더 이상 대체가 없을 때까지 반복합니다. 가능합니다. 따라서 각 행은 다음과 같습니다(첫 번째 행은 다음과 같습니다).

ID01 120120101
-> ID01 1 20120101
-> ID01 1 2 0120101
-> ID01 1 2 0 120101
-> ID01 1 2 0 1 20101
-> ID01 1 2 0 1 2 0101
-> ID01 1 2 0 1 2 0 101
-> ID01 1 2 0 1 2 0 1 01
-> ID01 1 2 0 1 2 0 1 0 1
at this point the "s" command fails, so "t1" doesn't branch

그리고 perl:

perl -pe 's/\S+$/join " ", split "", $&/e'

관련 정보