簡體   English   中英

sed - 基於先前給定用戶“選項”的特定正則表達式

[英]sed - specific regex(s) based on prior given user "options"

我目前正在嘗試通過以下代碼合並幾個 xml 文件:

rex_xh="-e '/^ *<\?xml[^>]*>$/d' -e s/^ *<\?xml[^>]+>//'"
rex_el="-e '/^[[:space:]]*$/d'"
rex_ts="-e "'s/^[ \t]*//'
while read xmldat ; do
        cat $xmldat | sed $rex_xh $rex_el $rex_ts >> "$OUTDIR/$OUTFILE" ; 
done << "$files"

本質上應該(對於每個文件)執行為:
cat $xmldat | sed -e '/^ *<\?xml[^>]*>$/d' -es/^ *<\?xml[^>]+>//' -e '/^[[:space:]]*$/d' -e "'s/^[ \t]*// >> "$OUTDIR/$OUTFILE"

但是,當嘗試執行此操作時,我收到此錯誤消息: sed: -e expression #1, char 1: unknown command: `'

如果我執行不帶變量的命令,而是直接輸入 sed 命令,它工作正常。 我錯過了什么? 我對變量擴展做錯了嗎?

根據(稍后給出的)用戶輸入,所有 3 個、僅 2 個或僅 1 個給定正則表達式應用於文件。 當前設置應該 - 刪除 xml 標題 - 刪除空行 - 刪除新行開頭的制表符和空格。

輸入示例

<?xml version="1.0" encoding="ISO-8859-15" standalone="no"?>
<RootNode xmlns="http://stub/example">
        
    <ExampleBase someattr="val">
                
        <InnerNode>Example</InnerNode>

    <ExampleBase someattr="val">

</RootNode>
                

預期結果(當 header 刪除,空格刪除和空行刪除是想要的)

<RootNode xmlns="http://stub/example">  
<ExampleBase someattr="val">
<InnerNode>Example</InnerNode>
<ExampleBase someattr="val">
</RootNode>
                

預期結果(僅需要刪除空格和刪除空行時)

<?xml version="1.0" encoding="ISO-8859-15" standalone="no"?>
<RootNode xmlns="http://stub/example">  
<ExampleBase someattr="val">
<InnerNode>Example</InnerNode>
<ExampleBase someattr="val">
</RootNode>
                

輸入示例 2

<?xml version="1.0" encoding="ISO-8859-15" standalone="no"?><RootNode xmlns="http://stub/example"><ExampleBase someattr="val"><InnerNode>Example
                              </InnerNode>

    <ExampleBase someattr="val">

</RootNode>
                

(是的,我們得到了那種奇怪的格式化 xml)

預期結果(當 header 刪除,空格刪除和空行刪除是想要的)

<RootNode xmlns="http://stub/example"><ExampleBase someattr="val"><InnerNode>Example
</InnerNode>
<ExampleBase someattr="val">
</RootNode>
                

筆記:

  • 這些文件並不總是有效的 xml 文件,因此我不能使用 xmllint 或其他 xml 工具
    • 例如沒有結束標簽
  • header dows 並不總是單獨在第一行,有時它不會被換行符成功。
  • 不同的正則表達式(例如 rex_xh)稍后將是可選的並由用戶輸入控制,因此將它們包裝在變量中的“必要性”
  • 將來應該很容易添加新的“選項”,因此在變量中使用“選項”的另一個原因。

有誰可以幫我離開這里嗎?

請嘗試按照awk代碼來處理由 OP 添加到問題中的少數邊緣情況。 僅在 GNU awk中使用所示示例編寫和測試。

awk -v RS="^$" '
match($0,/^<\?xml version="[^"]*" encoding="[^"]*" standalone="[^"]*"\?>/){
  val=substr($0,RSTART+RLENGTH)
  gsub(/\n/,"",val)
  gsub(/>[[:space:]]*</,">\n<",val)
  gsub(/[[:space:]]+</,"<",val)
  gsub(/>[[:space:]]*</,">\n<",val)
  print val
}
'  Input_file

解釋:簡單的解釋是,在awk程序中使用 2 個條件。 第一個:如果一行沒有值(通過正則表達式匹配^<\?xml version="[^"]*" encoding="[^"]*" standalone="[^"]*"\?>$ )並且它不是 NULL,然后使用gsub函數根據需要獲取 output 並打印該行的值存在於 val 變量中。



由 OP 編輯 - 實施的解決方案在擺弄之后,由於@RavinderSingh13 的幫助、評論和回答,以下代碼是最終解決方案(重要部分的片段):

rm_xmlhead=1;  # Option given via user input (later)
rm_tabspac=1;  # Option given via user input (later)
rm_emptyln=1;  # Option given via user input (later)
while read xmldat ; do
  cat $xmldat | awk -v rem_xh=$rm_xmlhead -v rem_ts=$rm_tabspac -v rem_el=$rm_emptyln ' {
          if(rem_xh) { sub(/^ *<\?xml[^>]+>/,"") }
          if(rem_ts) { sub(/^[[:space:]]+/,"") }
          if(rem_el && $0 =="" ) {next}
          print
      }' >> "$OUTPUT" ; 
done << "$files"

這將刪除空行、前導空格和制表符、xml 標頭,並且如果出現任何“新”要求,它很容易擴展……而且它讓我以后可以將每個刪除選項設為可選。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM