grep 和 IFS 的非常奇怪的行為
我在使用 grep 時遇到問題,返回的結果是“n-empty”,我的意思是沒有 ’n’ 字元…
這是腳本範例:
OLDIFS=$IFS IFS="\\n" i=$(grep -ril $1 *) echo $i IFS=$OLDIFS
我試過了
IFS='\n'
,IFS="\n"
但只有當我擺脫 IFS 時,結果才會顯示正確的路徑……我在
for theFile in $i; do......done
循環中使用結果,結果以正確的方式使用並theFile
正確顯示。唯一的問題是我沒有正確的控制台/文件輸出
$i
,這是一個戰略數據:我在控制台中看到的內容和寫入的文件(範例):
LecteurSy dicatio _sy dic/fiche_93.xml
應該顯示和書寫的內容(範例):
LecteurSyndication_syndic/fiche_93.xml
任何的想法 ?
編輯:在家玩的完整腳本;)
#!/bin/bash monTerminal=$(tty) ; monTerminal=${monTerminal:9} fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml" PWD="`pwd`" echo "== Recherche dans les fiches ==" > "$fichier" echo "Recherche : $1" >> "$fichier" echo "Dans : $PWD" >> "$fichier" OLDIFS=$IFS IFS="\\n" i=$(grep -ril $1 *) echo $i echo "== Liste des fichiers trouves ==" >> "$fichier" echo $i >> "$fichier" IFS=$OLDIFS #while read uneFiche for uneFiche in $i; do echo "================================" >> "$fichier" echo "== $uneFiche" >> "$fichier" echo "================================" >> "$fichier" echo "" >> "$fichier" xmlindent "$uneFiche" >> "$fichier" done < /home/robert/tmpCmdOpenFirst_liste.txt nano "$fichier" #rm $fichier
首先,您已設置
IFS
為\n
,而不是換行符。在 bash 中,您可以使用$'…'
將反斜杠序列解釋為控製字元:IFS=$'\n'
或者您可以選擇使用文字換行符。
IFS=' '
第二個問題是
IFS
擴展變數時很重要。所以在展開的時候需要設置$i
,其實什麼時候設置都無所謂i
。i=$(grep -ril -e "$1" -- *) set -f; OLDIFS="$IFS"; IFS=' ' for uneFiche in $i; do set +f; IFS="$OLDIFS" … done set +f; IFS="$OLDIFS"
此外,不要忘記在不拆分時引用變數,例如傳遞給
grep
. 如果模式以 開頭,請使用選項-
將其傳遞給。如果第一個文件名以 . 開頭,還要放在文件名的前面。此外,如果文件名包含 glob 字元,請在不引用變數擴展之前關閉 glob 。grep``-e``--``-``set -f
一種更簡單的方法是呼叫
grep
循環內的每個文件。另外一個好處是,您的腳本不會中斷包含換行符的文件名。for uneFiche in *; do if grep -qri -e "$1" -- "$uneFiche"; then … fi done
遵循您的問題描述並不容易。缺少唯一有用的資訊,即
grep -ril $1 *
(或者更確切地說是其中的一個樣本)的輸出以及問題所在的解釋。我認為問題是某些路徑中的空格。編輯:有您要求的樣本:
空白確實是’n’字元……
1_LecteurSy dicatio _sy dic/fiche_174.xml 2_Tra sformatio XSL_tif/fiche_174.xml 3_CorrigerTIF_cor/fiche_174.xml 4_Tra sformatio XSL_ge /fiche_174.xml
/編輯
IFS="\\n"
顯然是錯誤的,因為您可以輕鬆地使用echo "\\n"
. 我什至不確定是否\n
適用於 IFS 定義。改用 IFS=$’\n’ 或IFS=" "
編輯
$’\n’ 形式並不能解決問題。“空白行”形式使事情看起來正確,但結果不再以列表形式呈現(每行一個)。我保留“空白行”表格,因為它的結果大致是我需要的。
/編輯
如果您在行前恢復它,設置 IFS 對我來說沒有意義
for uneFiche in $i
。這樣你就可以影響這條線echo $i >> "$fichier"
,如果引用的話會容易得多:i="$(grep -ril $1 *)"
,echo "$i" >> "$fichier"
編輯
i="$(grep -ril $1 *)"
似乎沒有任何效果。/編輯
如果您在空格和分詞方面遇到此類問題,那麼使用這樣的管道可能會更容易:
grep -ril --null -- "$1" * | xargs -0 /my/script.sh
與
/my/script.sh
存在#!/bin/bash fichier="/home/importts/tmpCmdOpenFirst$monTerminal.xml" for uneFiche in "$@"; do echo "================================" echo "== $uneFiche" echo "================================" echo xmlindent "$uneFiche" done >> "$fichier"