각 필드에 후행 공백을 추가하고 싶습니다. 내 파일은 다음과 같습니다.
입력 파일:
A|B|C|D
출력 파일의 필드 1 길이는 다음과 같습니다.1
출력 파일의 필드 2 길이는 다음과 같습니다.3
출력 파일의 필드 3 길이는 다음과 같습니다.4
출력 파일의 필드 4의 길이는 다음과 같습니다.6
원하는 출력:
AB C D
쉘에서 이것을 달성하는 방법은 무엇입니까? 도와주세요
답변1
그리고 awk
:
awk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}' < input > output
올바른 공간 채우기 및 자르기를 수행합니다.
awk
구현 에 따라 길이는 바이트 또는 문자 단위입니다(멀티바이트 문자의 경우 다름). 어떤 경우에도 이러한 문자의 표시 너비를 기준으로 하지 않습니다(예: 이중 너비 또는 너비가 0인 문자 또는 터미널의 표시 너비가 1이 아닌 TAB).
예:
$ echo 'A|B|C|D' | awk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB C D
(이러한 문자소는 모두 A
B
C
D
하나의 문자로 구성되고, 각 문자소는 모든 로케일에서 1바이트로 구성되며, 각 문자소는 단일 너비입니다.)
$ echo 'A|B|Ç|D' | gawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB Ç D
$ echo 'A|B|Ç|D' | mawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB Ç D
Ç
(UTF-8에서는 2바이트, 너비 1문자)
$ echo $'A|B|C\u0327|D' | gawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB Ç D
$ echo $'A|B|C\u0327|D' | mawk -F'|' '{printf "%-1.1s%-3.3s%-4.4s%-6.6s\n", $1, $2, $3, $4}'
AB Ç D
1바이트, 1너비 C
와 0너비, 2바이트(UTF-8 형식)가 결합되어 발음 구별 부호와 결합되어 1너비, 2문자, 3바이트 글리프, 예에서 Ç
사전 조합된 U+00C7 이전 문자의 분해 버전을Ç
문자의 표시 너비를 고려하려면 일부 expand
구현(GNU는 아님 expand
)을 사용하고 입력에 TAB 문자가 포함되어 있지 않으며 입력 필드 중 어느 것도 할당된 너비를 먼저 초과하지 않는다고 가정하면 다음을 수행할 수 있습니다.
<input sed $'s/|/|\t/g;s/$/|\t/' | expand -t3,8,14,22 | sed 's/| //g' >output
출력은 다음 printf '%s\n' 'A|B|C|D' $'A|B|\uc7|D' $'A|B|C\u327|D'
을 제공해야 합니다.
AB C D
AB Ç D
AB Ç D
답변2
bash
쉘 함수 만 사용하세요 ...
제공된 샘플 데이터의 경우:
$ foo="A|B|C|D"; printf "%s%s %s %s \n" $(echo -e "${foo//|/ }" )
AB C D
$ foo="A|B|C\u0327|D"; printf "%s%s %s %s \n" $(echo -e "${foo//|/ }" )
AB Ç D
질문당 고정 필드 출력의 경우 지정된 최대 너비를 초과하는 입력 필드가 없다고 가정합니다.
$ foo="A|B|C|D"; printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e "${foo//|/ }" )
AB C D
다음과 같은 멀티바이트 문자의 경우: Ç
(셸 내장 및 독립 실행형 유틸리티)의 너비 지정자는 멀티바이트 문자가 아닌 바이트를 계산합니다. 따라서 "예기치 않은" 출력이 나타날 수 있습니다.printf
bash
$ foo="A|B|\uc7|D"; /bin/printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e "${foo//|/ }" )
AB Ç D
$ foo="A|B|\uc7|D"; /bin/printf "%-1.1s%-3.3s%-4.4s%-6.6s\n" $(echo -e "${foo//|/ }" ) | xxd
00000000: 4142 2020 c387 2020 4420 2020 2020 0a AB .. D .
$