답변:
나는 사용할 것이다 grep
:
$ grep -o . <<<"StackOver"
S
t
a
c
k
O
v
e
r
또는 sed
:
$ sed 's/./&\n/g' <<<"StackOver"
S
t
a
c
k
O
v
e
r
그리고 끝에 빈 공간이 문제가된다면 :
sed 's/\B/&\n/g' <<<"StackOver"
이 모든 것은 GNU / Linux를 가정합니다.
.
가 \B
(단어 경계와 일치하지 않음)으로 변경 되었습니다 .
sed
과 같이 두 번째를 떨어 뜨릴 수 있습니다 .sed -et -e's/./\n&/g;//D'
텍스트를 세로로 인쇄하려는 경우 문자 대신 그래 핀 클러스터를 분리 할 수 있습니다. 예를 들어 e
급성 악센트가있는 a를 사용하는 경우 :
그래 핀 클러스터를 ( e
의 급성 악센트 것 하나 개 그래 핀 클러스터) :
$ perl -CLAS -le 'for (@ARGV) {print for /\X/g}' $'Ste\u301phane'
S
t
é
p
h
a
n
e
(또는 grep -Po '\X'
PCRE 지원으로 빌드 된 GNU grep 사용)
문자 사용 (여기서는 GNU 사용 grep
) :
$ printf '%s\n' $'Ste\u301phane' | grep -o .
S
t
e
p
h
a
n
e
fold
은 문자를 구분하기위한 것이지만 GNU fold
는 멀티 바이트 문자를 지원하지 않으므로 대신 바이트를 구분합니다.
$ printf '%s\n' $'Ste\u301phane' | fold -w 1
S
t
e
�
�
p
h
a
n
e
에 StackOver ASCII 문자로 구성 (문자 당 한 바이트, 그래 핀 클러스터 당 하나 개의 문자 때문에), 세 가지 모두 같은 결과를 줄 것이다.
grep -Po
사람이 기대하는 것을하지 않는 것에 놀랐습니다 grep -P
.
grep -Po .
문자를 찾고 (개행 문자 다음에 결합하는 급성 악센트가 유효하지 않음), grep -Po '\X'
나를 위해 graphem 클러스터를 찾습니다. 제대로 작동하려면 최신 버전의 grep 및 / 또는 PCRE가 필요할 수 있습니다 (또는 시도해보십시오 grep -Po '(*UTF8)\X'
)
아래는 일반적인 것입니다 :
$ awk -F '' \
'BEGIN { RS = ""; OFS = "\n"} {for (i=1;i<=NF;i++) $i = $i; print }' <file_name>
echo StackOver | sed -e 's/./&\n/g'
S
t
a
c
k
O
v
e
r
bash에서 답변을 구체적으로 요청했기 때문에 다음을 순수 bash에서 수행하는 방법이 있습니다.
while read -rn1; do echo "$REPLY" ; done <<< "StackOver"
이것은 " here document " 의 끝에 줄 바꿈 문자를 붙 입니다. 이를 피하고 bash 루프를 사용하여 문자를 계속 반복 printf
하려면 줄 바꿈을 피하십시오.
printf StackOver | while read -rn1; do echo "$REPLY" ; done
또한 명령 행에서 Python 2를 사용할 수 있습니다.
python <<< "for x in 'StackOver':
print x"
또는:
echo "for x in 'StackOver':
print x" | python
또는 Python 3의 경우 ( 1_CR에서 언급 한 바와 같이) :
python3 -c "print(*'StackOver',sep='\n')"
fold (1)
명령을 사용할 수 있습니다 . grep
and 보다 더 효율적 sed
입니다.
$ time grep -o . <bigfile >/dev/null
real 0m3.868s
user 0m3.784s
sys 0m0.056s
$ time fold -b1 <bigfile >/dev/null
real 0m0.555s
user 0m0.528s
sys 0m0.016s
$
한 가지 중요한 차이점은 fold가 출력에서 빈 줄을 재현한다는 것입니다.
$ grep -o . <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$ fold -b1 <(printf "A\nB\n\nC\n\n\nD\n")
A
B
C
D
$
다음과 같은 멀티 바이트 문자를 처리 할 수 있습니다.
<input \
dd cbs=1 obs=2 conv=unblock |
sed -e:c -e '/^.*$/!N;s/\n//;tc'
버퍼링이없고 문자가 전체 가 되 자마자 인쇄되기 때문에 라이브 입력으로 작업 할 때 매우 편리합니다 .
sed
입니다. 이것이 바로 스크립트입니다. 나는 지금 당장 글을 쓰지 않을 것입니다. 그러나 터미널을 읽을 때 정말 유용합니다.
dd
나오지도의 동작은 POSIX에 따라 지정 될 수 있도록 출력이 더 이상 텍스트를하지 않도록, 멀티 바이트 문자를 중단합니다.
bash에서 :
이것은 모든 텍스트에서 작동하며 bash 내부 (외부 유틸리티는 호출되지 않음)에서만 작동하므로 매우 짧은 문자열에서는 빠릅니다.
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
(set -- "${BASH_REMATCH[@]:1}"; IFS=$'\n'; echo "$*")
산출:
S
t
é
p
h
a
n
e
á
à
é
è
ë
ê
ế
e
IFS를 변경하고 위치 매개 변수를 변경해도 괜찮다면 서브 쉘 호출을 피할 수도 있습니다.
str="Stéphane áàéèëêếe"
[[ $str =~ ${str//?/(.)} ]]
set -- "${BASH_REMATCH[@]:1}"
IFS=$'\n'
echo "$*"
s=stackoverflow;
$ time echo $s | fold -w1
s
t
a
c
k
o
v
e
r
real 0m0.014s
user 0m0.000s
sys 0m0.004s
여기에 업데이트 는 해키 | 빠른 | pureBashBased 방법입니다!
$ time eval eval printf \'%s\\\\n\' \\\${s:\{0..$((${#s}-1))}:1}
s
t
a
c
k
o
v
e
r
real 0m0.001s
user 0m0.000s
sys 0m0.000s
더 굉장히
function foldh ()
{
if (($#)); then
local s="$@";
eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
else
while read s; do
eval eval printf \'%s\\\\n\' \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
done;
fi
}
function foldv ()
{
if (($#)); then
local s="$@";
eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
else
while read s; do
eval eval echo \\\"\\\${s:\{0..$((${#s}-1))}:1}\\\";
done;
fi
}
fold -b1
있습니까?