2017-04-12 18 views
0

我有以下bash腳本:遍歷文件和SED替代每一行

while IFS= read -r line; do 
     line=$(echo $line | sed "s/\'/\'\'/") 

     [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}" 
done < <(dos2unix < file) 

編輯的腳本的版本,而DOS2UNIX的:

while IFS= read -r line && line=${line%$'\r'}; do 
    [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}" 
done < file 

我想替換每個單引號中的「文件」與2撇號之前我循環通過它。我怎樣才能做到這一點?我很感激任何有關這兩個版本的建議。 重要 Im NOT允許修改原始文件!

+0

你''在那裏。這是XML嗎?如果是這樣,那麼使用XML解析器是一個非常好的主意。 – Sobrique

+0

@Sobrique Im從文本文件中提取數據以創建一個sql文件,然後執行.read file.sql來創建和加載數據庫 –

+0

「不能正常工作」是什麼意思? –

回答

0

這是單獨sed作業:

sed 's/\r$//;s/\'/\'\'/g;s/^<ID>\(.*\)/\1/p;d' < file 

的步驟是:

  1. sed接受帶有換行符,分號分隔或作爲多個-e選項給出多個命令。
  2. sed 's/\r$//;刪除每行末尾的CR,如dos2unix
  3. g標誌加到s/\'/\'\'/表示代替全部出現在行中;默認是隻替換一個。
  4. s/^<ID>\(.*\)/\1/這是否bash的正則表達式匹配和在結束時p標誌的等效使得SED打印匹配的行現在,因爲
  5. d命令刪除行,以便它不會通過默認打印(你可以用-n選項代替)。

在一個側面說明,我的zsh不接受'\',所以我可能會寫

sed -n -e 's/\r$//' -e "s/'/''/g" -e 's/^<ID>\(.*\)/\1/p' 

它應該是等價的,只是切換的報價風格,不同的選項和-n而不是最後的d

+0

這些命令說明了爲什麼像sed這樣的工具受限於人類大腦一旦指令不再微不足道就破譯其「高效」語法的能力。 – Fred

+0

順便說一下,這不是對「sed」或你提出的解決方案的批評,而只是一個觀察結果,顯然需要在可讀性和可維護性之間進行權衡以實現「完成任何事情的魔術單行程」。 – Fred

+0

@Fred,這些是4800波特電傳終端的日子,每一次擊鍵都會產生明顯的延遲,所以每個人都想盡可能少輸入。 –

0

雖然這不是一個「解決方案」(您的問題不清楚什麼不在您的代碼中工作),但您當然應該避免爲每條線路調用sed。從產生不正確結果的意義上講,這不是「錯誤的」,但它太慢了,應該避免。有幾種方法可以更快更簡單地進行編碼。

這樣來做:

while IFS= read -r line; do 
     [[ $line =~ ^\<ID\>(.*) ]] && printf "${BASH_REMATCH[1]}" 
done < <(dos2unix < file | sed "s/\'/\'\'/") 
+0

這正是我想要做的,但是當我添加sed部分時,腳本沒有做任何事情 –