문자열이 주어지면 쉼표 앞에 문자가 없고 문자가 없는 각 쉼표 사이에 해당 문자를 처음에 강제로 적용 ,,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-/'