2017-02-13 51 views
1

我有JSON文件,註釋了我在使用jq進行操作之前刪除的註釋。我剛剛遇到了一個有趣的問題,我收到了帶有註釋註釋的JSON文件,其中包含一些富文本引號字符(十六進制93和十六進制94)。我現有的sed點.字符與這些字符不匹配。這裏是一個演示:LC_ALL = C總是用於非特定於語言環境的sed操作?

首先,輸入:

% echo -e '# \x93text\x94\n{"a":1}' | od -c 
0000000 #  223 t e x t 224 \n { " a " : 1 } 
0000020 \n 
0000021 
% 

這裏是變換:

% echo -e '# \x93text\x94\n{"a":1}' | sed 's/^\s*#.*//' | od -c 
0000000 223 t e x t 224 \n { " a " : 1 } \n 
0000017 
% 

注意的是,在sed的表達點字符不匹配的十六進制93字符。然而,如果我包括LC_ALL=C

% echo -e '# \x93text\x94\n{"a":1}' | LC_ALL=C sed 's/^\s*#.*//' | od -c 
0000000 \n { " a " : 1 } \n 
0000011 
% 

然後在sed的表達點字符確實匹配的六角93和六角94個字符。 sed文檔部分Locale Considerations提到括號表達式,但上面的行爲似乎證明了這個問題發生在其他地方。

這是有趣的是,缺失的,而不是替代並沒有表現出這樣的問題:

% echo -e '# \x93text\x94\n{"a":1}' | sed '/^\s*#.*/d' | od -c   
0000000 { " a " : 1 } \n 
0000010 

鑑於我上標註的JSON文件上進行操作,我想加入LC_ALL=C到SED報表解決方案合理。

所以,我的問題:是使用LC_ALL=C的東西,我一直想用做非特定於語言環境時sed轉換(如將適用於註釋JSON文件)?如果沒有,有什麼替代方案可以避免我上面顯示的問題?

我的環境:

  • 的CentOS 7.3內核3.10.0-514.6.1.el7.x86_64]
  • 的sed(GNU SED)4.2.2 [沉渣 - 4.2.2-5。 el7.x86_64]
  • 擊4.2.46(1)[bash的-4.2.46-21.el7_3.x86_64]
+0

不是問題KSH(環境cerftainly不同),但嘗試下你的線我得到這可能有助於'echo -e'#\ x93text \ x94 \ n {「a」:1}'| sed'/^[[::space:]]**#.*/ s // [HERE] /'| od -c'give'0000000 [HERE] 223文本224 \ n {「a 0000020」:1} \ n '所以sed估計在換行時達到了行尾,而不是在選擇 – NeronLeVelu

+0

@NeronLeVelu是的,它非常奇怪的行爲在任何情況下。由於sed網頁建議包括'LC_ALL = C',這讓我想知道這是否是sed中的錯誤的解決方法,或者它是一個難以理解的功能。 –

回答

0

C語言環境是指是最簡單的語言環境的特殊區域。你也可以說,雖然其他語言環境適用於人類,但C語言環境適用於計算機。 在C語言環境中,字符是單個字節,字符集是ASCII

在某些系統上,與POSIX語言環境有區別,例如未定義非ASCII字符的排序順序。

所以LC_ALL = C是考慮到非第8位字符的安全方式。

見comparaison

與LC,sed的數量作爲字符

echo -e '# \x93text\x94\n{"a":1}' | LC_ALL=C sed 's/[^[:alnum:]]/[HERE:&] /g' | od -c 
0000000 [ H E R E : # ]  [ H E R E : 
0000020 ]  [ H E R E : 223 ]  t e x t [ 
0000040 H E R E : 224 ]  \n [ H E R E : { 
0000060 ]  [ H E R E : " ]  a [ H E R 
0000100 E : " ]  [ H E R E : : ]  1 [ 
0000120 H E R E : } ]  \n 

沒有LC的一部分,sed的不算作一部分字符考慮到([[:alnum:]][^[:alnum:]]看到第8位字符)

echo -e '# \x93text\x94\n{"a":1}' | sed 's/[[:alnum:]]/[HERE:&] /g' | od -c 
0000000 #  223 [ H E R E : t ]  [ H E R 
0000020 E : e ]  [ H E R E : x ]  [ H 
0000040 E R E : t ]  224 \n { " [ H E R E 
0000060 : a ]  " : [ H E R E : 1 ]  } 
0000100 \n 

echo -e '# \x93text\x94\n{"a":1}' | sed 's/[^[:alnum:]]/[HERE:&] /g' | od -c 
0000000 [ H E R E : # ]  [ H E R E : 
0000020 ]  223 t e x t 224 \n [ H E R E : { 
0000040 ]  [ H E R E : " ]  a [ H E R 
0000060 E : " ]  [ H E R E : : ]  1 [ 
0000100 H E R E : } ]  \n 
+0

因此,你認爲我甚至可以在腳本中使用這個作爲全局選項('export LC_ALL = C')?即使用於其他目的的字符串操作涉及特定於區域的數據,那麼我猜測替換仍然會做正確的事情。例如,一個's/$ LOCALE_WORD/$ REPLACEMENT /'這兩個單詞是特定於語言環境的,它仍然可以在LC_ALL = C下正常工作,對吧?這會激勵我將這個設置爲一個環境變量,而不是每次使用sed時的變量。你怎麼看? –

+0

這是一個sed行爲,所以只需將其添加到sed(批處理中的每個sed),以避免其他應用程序出現其他應用程序的其他意外行爲(只是我的觀點和我在批處理中使用它的方式) – NeronLeVelu

+0

非常好。我會去做。感謝您花時間回答。標記爲接受的答案。 –

相關問題