반복되는 문자 사이에 문자를 삽입합니다.

반복되는 문자 사이에 문자를 삽입합니다.

문자열이 주어지면 쉼표 앞에 문자가 없고 문자가 없는 각 쉼표 사이에 해당 문자를 처음에 강제로 적용 ,,a,,,b,,,,하고 싶습니다 . -결과는 다음과 같습니다 -,-,a,-,-,b,-,-,-,-.

echo ",,a,,,b,,,," | sed 's/,/,-/g' | sed 's/-\([^,]\)/\1/g' | sed 's/^,/-&/g'

다음으로 이어진다:-,-,a,-,-,b,-,-,-,-

하지만 문제는 sed를 세 번 호출하는 것이 매우 비효율적이라는 것입니다.매우 긴 반복sed로 이 작업을 수행할 수 있는 방법이 있습니까?정규식, 또는 다른 도구한 번 전화해?

답변1

(echo ,,a,,,b,,,,; echo a,,b) | perl -pe 's/(^|,)\K(?=(,|$))/-/g' 
-,-,a,-,-,b,-,-,-,-
a,-,b

sed올해 중 한 학기 공부해야 할 것 같아요 .

답변2

하나이를 수행하는 방법은 sed루프를 사용하는 것입니다.

$ echo ",,a,,,b,,,," | sed ':a; s/\(^\|,\)\(,\|$\)/\1-\2/; ta'
-,-,a,-,-,b,-,-,-,-

귀하의 버전이 확장 정규식을 지원하는 경우 더 쉽게 읽을 수 있도록 단순화할 수 있습니다.

sed -E ':a; s/(^|,)(,|$)/\1-\2/; ta'

또 다른 방법은 에서 이 작업을 수행하고 perl쉼표로 구분된 필드로 분할한 다음 빈 필드를 하이픈에 매핑하는 것입니다.

perl -anle 'print join ",", map { $_ ? $_ : "-" } split(",", $_, -1)'

(후행 빈 필드를 포함하여 추가 매개변수를 강제 적용합니다 -1).split

답변3

echo ",,a,,,b,,,," |
  awk -v 'FS=,' -v 'OFS=,' '{for (i=1; i<=NF; i++) sub(/^$/,"-",$i); print};'

답변4

$ echo ',,a,,,b,,,,' | sed 's/\(\([^,]\+,\)*\),/\1-,/g; s/\(^\|,\)$/\1-/'
-,-,a,-,-,b,-,-,-,-

두 번째 표현식( ) 은 패턴 공간의 끝에 도달하면 일치를 중지하는 것처럼 보이기 s/\(^\|,\)$/\1-/때문에 필요합니다 . 비록 유일한 표현식이 이면 여전히 a와 일치할 수 있지만 말입니다 .sed$s/\(\([^,]\+,\)*\)\(,\|$\)/\1-\3/g

물론 sed -E이렇게 하면 읽기가 더 쉬워지지만 다른 점에서는 동일합니다.

sed -E 's/(([^,]+,)*),/\1-,/g; s/(^|,)$/\1-/'

관련 정보