變數列印了相同的值,但實際上值是 diff
用於擷取 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'
這
$'TOPIC\r'
是您的printf
實現給出的視覺表示,用於表示該變數的內容。它使用 ksh93 的$'...'
引用形式(現在也受zsh
,bash
和其他一些 shell 支持)為您提供該表示。在這些 shell 中,var=$'TOPIC\r'
將創建一個$var
具有相同內容的變數。在那種形式的引用中,\r
代表一個輸入符。這是一個字元,當發送到終端時會使終端將游標移動到行首。它是終端的控製字元,它不是帶有與之關聯的字形的普通字元。
printf 'ABC\rX\n'
(
printf
, 在其格式參數中也辨識\r
為 CR 字元的含義) 顯示為:XBC
如果你寫:
printf 'ABC\rX\n' | pv -qL3
慢下來,你可以看看會發生什麼。
要刪除它,使用類似 ksh93 的 shell(ksh93、zsh、bash 或 mksh),您可以這樣做
var=${var//$'\r'}
\r
也被歸類為[:space:]
字元。因此,您還可以使用以下方法刪除所有空格字元:var=${var//[[:space:]]}
要僅刪除該 CR 字元(變數末尾的字元):
var=${var%$'\r'}
(應該可以移植到更多的shell)。
POSIXly(如在可移植
sh
腳本中),您可以執行以下操作:var=$(printf %s "$var" | tr -d '\r')
儘管請注意,它還會
\n
從變數內容的末尾刪除換行符(又名換行符又名 LF aka )。附帶說明一下,
[[ TOPIC = $var ]]
(zsh 和 bash 也支持一個ksh
ism)是一個模式匹配運算符,而不是一個相等性測試運算符(除了zsh
不模擬 ksh/bash 時),您需要[[ TOPIC = "$var" ]]
測試相等性,例如var=*; [[ TOPIC = $var ]]
會返回true(並且var='[x]'; [[ $var = $var ]]
會返回false)。還要記住,
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$