tr
문자열에서 "불법" 문자가 모두 "허용" 문자 집합 외부에 있는 "불법" 문자를 대체 문자 (즉이는 허용되는 문자 세트에 추가됩니다. 그러나 이 -c
옵션을 명시적인 *
반복 지정자 또는 "세트 2"의 암시적 확장 과 함께 사용하면 tr
추가추가의출력용 대체 문자의 인스턴스입니다.
다시 나타나다
- "허용되는" 문자를
a-n
문자 그대로 로 지정합니다abcdefghijklmn
. - 대체 문자를 로 둡니다
z
. - 입력 문자열을
hell
또는 로 둡니다hello
. 예상되는 출력 문자열은 thenhell
및 입니다hellz
.
데모
잘못된 문자가 존재합니다. 암시적 세트 2 확장자입니다.
$ echo "hello" | tr -c 'abcdefghijklmn' 'z' hellzz
예상되는 출력은 입니다
hellz
.문자만 허용되며 암시적 세트 2 확장자입니다.
$ echo "hell" | tr -c 'abcdefghijklmn' 'z' hellz
예상되는 출력은 입니다
hell
.잘못된 문자가 존재합니다. 확장자 2개를 명시적으로 설정했습니다.
$ echo "hello" | tr -c 'abcdefghijklmn' '[z*]' hellzz
예상되는 출력은 입니다
hellz
.문자만 허용되며 명시적으로 확장자 2개를 설정합니다.
$ echo "hell" | tr -c 'abcdefghijklmn' '[z*]' hellz
예상되는 출력은 입니다
hell
.echo-pipe 대신 here-string을 사용하는 경우에도 동일한 일이 발생합니다(사실 here-string은 제가 이 효과를 처음 발견했을 때 사용한 구성이었습니다).
$ tr -c 'abcdefghijkl' '[z*]' <<< "hello" hellzz
tr
왜 여기에 하나를 추가 해야 합니까 z
?
이것은 Linux에서 bash, UTF-8 로케일을 사용하고 tr
GNU coreutils 8.25 및 8.30을 사용합니다.
답변1
echo
이는 인쇄하라고 지시한 내용의 끝에 개행 문자가 추가되기 때문입니다 . 여기서 문자열을 사용하는 경우에도 마찬가지입니다.
따라서 echo "hello"
실제로 인쇄됩니다 hello\n
.
$ echo hello | od -c
0000000 h e l l o \n
0000006
이것이 바로 당신이 이것을 보는 이유입니다:
$ echo "hell" | tr -c 'abcdefghijklmn' 'z'
hellz$
거기에는 후행 줄 바꿈이 없으며 $
내 프롬프트가 마지막에 나타납니다 . 이는 끝에 인쇄된 내용 이 로 대체되기 때문 z
입니다 .\n
hello\n
z
printf
$ printf "hello" | tr -c 'abcdefghijklmn' 'z'
hellz$
( printf %s "$string"
임의 문자열의 경우 no )printf "$string"
또는 echo
이를 지원하는 것을 사용하는 경우 다음을 사용하십시오 echo -n
.
$ echo -n "hello" | tr -c 'abcdefghijklmn' 'z'
hellz$
echo
또는 표준 UNIX (및 옵션이 모두 활성화된 경우 내장된 것과 같은 ) 가 있는 경우 echo
출력을 중지하는 원인을 사용하십시오.bash
posix
xpg_echo
\c
echo
$ echo 'hello\c' | tr -c 'abcdefghijklmn' 'z'
hellz$
그러나 출력이 여전히 올바른 텍스트가 되도록 입력에 해당 줄 구분 기호를 유지하려고 할 가능성이 높습니다.
printf '%s\n' "$string" | tr -c 'abcdefghijklmn\n' '[z*]'
(대신 표준 POSIX 구문이 사용되어 줄 바꿈을 더 명확하게 printf
추가 echo
하고 문자로 시작 -
하거나 문자를 포함하는 \
문자열과 관련된 문제를 방지합니다.)
tr
또한 구현 에 따라 개별적으로 문자로 디코딩할 수 없는 바이트가 남을 수 있지만(변경되지 않음 z
) 일부 다른 경우(예: GNU)에서는 tr
문자당 단일 문자(및 로케일 세트) 바이트가 있는 텍스트에 대해서만 작동합니다.
sed
또 다른 접근 방식은 적어도 GNU 구현에서는 이와 관련하여 더 잘 작동하는 방법을 사용하는 것입니다 .
sed 's/[^abcdefghijklmnz]/z/g'
sed
그 일을 수행하다콘텐츠줄 바꿈이 자동으로 유지됩니다.