줄이 매우 길고 읽기 쉽도록 일반 텍스트의 한 줄에 4자마다 공백을 삽입하고 싶습니다. 가장 쉬운 방법은 무엇입니까? 또한 파이프에서 라인을 입력할 수도 있어야 합니다. 예를 들어
echo "foobarbazblargblurg" | <some command here>
주어진
foob arba zbla rgbl urg
답변1
sed를 다음과 같이 사용하세요:
$ echo "foobarbazblargblurg" | sed 's/.\{4\}/& /g'
foob arba zbla rgbl urg
답변2
다음과 같은 간단한 예를 사용할 수 있습니다.
$ echo "foobarbazblargblurg" | fold -w4 | paste -sd' ' -
foob arba zbla rgbl
답변3
Bash에서만 외부 명령이 없습니다.
str="foobarbazblargblurg"
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
또는 한 줄 파이프라인 버전으로:
echo foobarbazblargblurg |
{ IFS= read -r str; [[ $str =~ ${str//?/(.)} ]]; \
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"; }
작동 방식은 정규식 일치를 위해 문자열의 각 문자를 "(.)"로 변환하고 를 사용하여 캡처한 =~
다음 필요에 따라 그룹화하여 배열에서 캡처된 표현식을 출력하는 것입니다 BASH_REMATCH[]
. 선행/후행/중간 공백을 유지하고, "${BASH_REMATCH[@]:1}"
생략하려면 주변 따옴표를 제거하세요.
여기서는 인수를 처리하거나 인수가 없는 경우 stdin을 읽는 함수로 래핑됩니다.
function fmt4() {
while IFS= read -r str; do
[[ $str =~ ${str//?/(.)} ]]
printf "%s%s%s%s " "${BASH_REMATCH[@]:1}"
done < <( (( $# )) && printf '%s\n' "$@" || printf '%s\n' $(< /dev/stdin) )
}
$ echo foobarbazblargblurg | fmt4
foob arba zbla rgbl urg
카운트를 쉽게 매개변수화하여 형식 문자열을 적절하게 조정할 수 있습니다.
뒤에 공백을 추가하고 printf
이것이 문제인 경우 하나 대신 두 개를 사용하십시오.
printf "%s%s%s%s" "${BASH_REMATCH[@]:1:4}"
(( ${#BASH_REMATCH[@]} > 5 )) && printf " %s%s%s%s" "${BASH_REMATCH[@]:5}"
첫 번째 printf
는 처음 4개 문자까지 인쇄하고, 두 번째는 그룹을 구분하는 선행 공백을 사용하여 나머지 모든 문자(있는 경우)를 조건부로 인쇄합니다. 테스트에서는 4개 요소 대신 5개 요소에 대해 0번째 요소를 설명합니다.
노트:
- 대신 쉘을 사용하여 의도를 더 명확하게 만들
printf
수 있지만 멀티 바이트 문자로부터 안전하지는 않습니다. 위의 내용은 bash 버전이 지원하는 경우 멀티바이트 문자로부터 안전합니다.%c
%s
%c
- 쉘은
printf
인수가 부족할 때까지 형식 문자열을 재사용하므로 한 번에 4개의 인수만 사용하고 후행 인수를 처리합니다. 따라서 여기의 다른 답변 중 일부와 달리 엣지 케이스가 필요하지 않습니다. 이는 아마도 틀렸을 것입니다. BASH_REMATCH[0]
는 일치하는 전체 문자열이므로 인덱스 1부터 시작하는 문자열만 출력됩니다.printf -v myvar ...
변수에 저장하는 대신 사용myvar
(일반적인 읽기 루프/서브쉘 동작에 따라 다름)printf "\n"
필요한 경우 추가
zsh
match[]
대신 배열을 사용 하고 일치하는 동안 0개의 요소가 유지되지 않으므로 BASH_REMATCH[]
모든 인덱스에서 1을 빼면 위의 작업이 제대로 작동하도록 할 수 있습니다.zsh
답변4
grep
다음은 sum을 사용한 예입니다 xargs
.
$ echo "foobarbazblargblurg" | grep -o .... | xargs
foob arba zbla rgbl