2014-12-30 71 views
0

我試圖放在一起bash腳本,將搜索一堆文件,如果它發現一個文件中的特定字符串,它會在該行後添加一個新行然後轉到下一個文件。bash,在一行後添加字符串

#! /bin/bash 
echo "Creating variables" 
SEARCHDIR=testfile 
LINENUM=1 
find $SEARCHDIR* -type f -name *.xml | while read i; do 
echo "Checking $i" 

    ISBE=`cat $i | grep STRING_TO_SEARCH_FOR` 
    if [[ $ISBE =~ "STRING_TO_SEARCH_FOR" ]] ; then 
    echo "found $i" 
    cat $i | while read LINE; do 
     ((LINENUM=LINENUM+1)) 
     if [[ $LINE == "<STRING_TO_SEARCH_FOR>" ]] ; then 
     echo "editing $i" 
     awk -v "n=$LINENUM" -v "s=new line to insert" '(NR==n) { print s } 1' $i 
     fi 
    done 
    fi 
LINENUM=1 
done 

我遇到麻煩位

awk -v "n=$LINENUM" -v "s=new line to insert" '(NR==n) { print s } 1' $i 

如果我只是用$ I末,它將輸出內容到屏幕上,如果我使用$i > $i那麼它將只擦除文件,如果我使用$i >> $i它將陷入循環,直到磁盤填滿。

有什麼建議嗎?

+1

然後就重定向到一個臨時文件,然後將其移動到您的原始文件。另外,我猜你的代碼可以使用正確的工具減少很多。一個'find'和'awk'應該或多或少夠用,而你使用很多不同的東西。 – fedorqui

回答

1

不幸的是AWK這麼想​​的具有就地替代選項,類似的sed的-i,這樣你就可以創建一個臨時文件,然後將其刪除:

awk '{commands}' file > tmpfile && mv tmpfile file 

,或者如果你有GNU awk 4.1.0 or newer,在-i inplace是添加,所以你可以做:

awk -i inplace '{commands}' file 

修改原來

1

如果你可以,也許使用臨時文件?

~$ awk ... $i > tmpfile 
~$ mv tmpfile $i 

或者乾脆awk ... $i > tmpfile && mv tmpfile $i

需要注意的是,你可以使用mktemp創建此臨時文件。

否則,sed的您可以在比賽後立即插入一行:

~$ cat f 
auie 
nrst 
abcd 
efgh 
1234 

~$ sed '/abcd/{a\ 
new_line 
}' f 
auie 
nrst 
abcd 
new_line 
efgh 
1234 

的命令搜索,如果匹配線/abcd/,如果是的話,它會追加(a\)行new_line

而且由於sed作爲-i取代內嵌,你可以這樣做:

if [[ $ISBE =~ "STRING_TO_SEARCH_FOR" ]] ; then 
    echo "found $i" 
    echo "editing $i" 
    sed -i "/STRING_TO_SEARCH_FOR/{a 
\new line to insert 
}" $i 
fi 
+2

最好使用'awk'...'file> tmp && mv tmp file',就像user00 ... 0001一樣。在'awk'失敗的情況下,'&&'技巧可以防止在輸出錯誤的情況下覆蓋'file'。 – fedorqui

+0

@fedorqui注意到 – fredtantini

+1

謝謝,我用sed選項。我發現我的循環也有問題,但sed方法允許我發現它。 – vmos

1
#cat $i | while read LINE; do 
# ((LINENUM=LINENUM+1)) 
# if [[ $LINE == "<STRING_TO_SEARCH_FOR>" ]] ; then 
# echo "editing $i" 
# awk -v "n=$LINENUM" -v "s=new line to insert" '(NR==n) { print s } 1' $i 
# fi 
# done 

# replaced by 
sed -i 's/STRING_TO_SEARCH_FOR/&\n/g' ${i} 

或用awk代替sed的

# ISBE=`cat $i | grep STRING_TO_SEARCH_FOR` 
# if [[ $ISBE =~ "STRING_TO_SEARCH_FOR" ]] ; then 
#by 
if [ $(grep -c 'STRING_TO_SEARCH_FOR' ${i}) -gt 0 ]; then 
# if file are huge, if not directly used sed on it, it will be faster (but no echo about finding the file) 
相關問題