다음 구문을 사용하여 xml 파일에서 단어를 캡처합니다. 또한 xargs를 사용하여 공백을 제거합니다.
var=` find /tmp -name '*.xml' -exec sed -n 's/<Name>\([^<]*\)<\/Name>/\1/p' {} + | xargs `
echo $var
TOPIC
지금까지는 괜찮아 보이는데
하지만 printf는 다른 것을 보여줍니다
printf "%q\n" "$var"
$'TOPIC\r'
더 자세히 살펴보겠습니다.
[[ TOPIC == $var ]] && echo they are equal
"그들은 동일합니다"를 인쇄하지 않습니다
하지만 $var를 인쇄하면 다음과 같은 결과가 나옵니다.
echo $var
TOPIC
그래서 상황이 분명해진 후에
가장 큰 문제는 다음과 같습니다.
변수에서 추가 문자( $ , \r )를 제거하는 방법 -
$'TOPIC\r'
답변1
이는 이 변수의 내용을 나타내기 위해 구현에서 제공하는 시각적 표현입니다 $'TOPIC\r'
. 이 표현을 제공하기 위해 printf
ksh93의 $'...'
인용 형식(현재 다른 쉘에서도 지원됨 zsh
) 을 사용합니다. bash
이러한 셸에서는 동일한 내용으로 var=$'TOPIC\r'
변수가 생성됩니다 . $var
이 인용 형식에서는 \r
캐리지 리턴 문자를 나타냅니다.
이것은 터미널로 전송될 때 커서를 줄의 시작 부분으로 이동시키는 문자입니다. 문자 모양이 연결된 일반 문자가 아닌 터미널의 제어 문자입니다.
printf 'ABC\rX\n'
( printf
, 그 안에는체재매개변수는 \r
CR(문자의 의미)로도 인식되며 다음과 같이 표시됩니다.
XBC
당신이 쓰는 경우 :
printf 'ABC\rX\n' | pv -qL3
속도를 늦추면 무슨 일이 일어나는지 볼 수 있습니다.
이를 제거하려면 ksh93과 유사한 셸(ksh93, zsh, bash 또는 mksh)을 사용하여 다음을 수행할 수 있습니다.
var=${var//$'\r'}
\r
[:space:]
캐릭터 로도 분류됩니다 . 따라서 다음을 사용하여 모든 공백 문자를 제거할 수도 있습니다.
var=${var//[[:space:]]}
CR 문자(변수 끝에 있는 문자)만 제거하려면 다음을 수행하십시오.
var=${var%$'\r'}
(더 많은 쉘에 이식 가능해야 합니다).
POSIXly(이식 가능한 스크립트에서와 마찬가지로 sh
) 다음을 수행할 수 있습니다.
var=$(printf %s "$var" | tr -d '\r')
그러나 \n
변수 내용의 끝에서 개행(또는 개행, 일명 LF)도 제거된다는 점에 유의하세요.
그런데 ism [[ TOPIC = $var ]]
( ksh
zsh 및 bash에서도 지원됨)은 동등성 테스트 연산자가 아닌 패턴 일치 연산자입니다(ksh/bash를 에뮬레이션하지 않는 경우 제외 ). 동등성 테스트를 수행 zsh
해야 합니다 .[[ TOPIC = "$var" ]]
var=*; [[ TOPIC = $var ]]
진짜예를 들어 (그리고 var='[x]'; [[ $var = $var ]]
반환됩니다잘못된).
또한 기억해주세요echo
임의의 데이터를 출력하는 데 사용할 수 없습니다.그리고매개변수 확장은 일반적으로 인용되어야 합니다..
$ var=$'TOPIC\r'
$ printf '%s\n' "$var" # zsh (my shell) builtin
TOPIC
$ printf '%q\n' "$var"
TOPIC$'\r'
$ /usr/bin/printf '%q\n' "$var" # GNU printf
'TOPIC'$'\r'
$ (export var; bash -c 'printf "%q\n" "$var"') # bash builtin
$'TOPIC\r'
$ (export var; ksh93 -c 'printf "%q\n" "$var"') # ksh93 builtin
$'TOPIC\r'
$ (export var; dash -c 'printf "%q\n" "$var"')
dash: 1: printf: %q: invalid directive
%q
표준 printf
지시문은 아니며 모든 구현이 이를 지원하는 것은 아니며 동작은 구현마다 다릅니다. sed -n l
문자열의 명확한 시각적 표현을 얻는 이식 가능/표준 방법입니다(출력은 구현마다 다르지만).
$ printf '%s\n' "$var" | sed -n l
TOPIC\r$
즉, $
줄의 끝을 표시합니다(뒤에 공백이 있는 줄에 유용함).
$ var=${var//$'\r'}
$ printf '%s\n' "$var" | sed -n l
TOPIC$
답변2
is 기호는 \r
C에서 상속되었으며 캐리지 리턴 문자를 나타냅니다. 파일에 DOS/Windows 스타일 CRLF 줄 끝이 있을 가능성이 높습니다. CR을 다른 문자로 처리 sed
하면 xargs
전달됩니다. 같은 줄에 있는 <Name>...</Name>
태그 이외의 다른 것도 이 sed에 의해 전달됩니다.
$ echo 'foo <Name>bar</Name><Num>123</Num>' | sed 's/<Name>\([^<]*\)<\/Name>/\1/'
foo bar<Num>123</Num>
sed
다음과 같이 XML 파일에서 필드를 선택하는 경우 줄 주위의 다른 내용도 제거 할 수 있습니다 .
$ echo 'foo <Name>bar</Name><Num>123</Num>' | sed 's/.*<Name>\([^<]*\)<\/Name>.*/\1/'
bar
또한 .*
.