긴 줄에서 4자마다 공백을 삽입하는 방법은 무엇입니까?

긴 줄에서 4자마다 공백을 삽입하는 방법은 무엇입니까?

줄이 매우 길고 읽기 쉽도록 일반 텍스트의 한 줄에 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"필요한 경우 추가

zshmatch[]대신 배열을 사용 하고 일치하는 동안 0개의 요소가 유지되지 않으므로 BASH_REMATCH[]모든 인덱스에서 1을 빼면 위의 작업이 제대로 작동하도록 할 수 있습니다.zsh

답변4

grep다음은 sum을 사용한 예입니다 xargs.

$ echo "foobarbazblargblurg" | grep -o .... | xargs
foob arba zbla rgbl

관련 정보