簡體   English   中英

從目錄遞歸檢查內容和移動文件

[英]Checking content and moving files recursively from a directory

我有一個目錄,其中包含 header 和有效負載 xml 文件,名稱如下(no.xml 擴展名存在):

File1
File1_PAYLOAD
File2
File2_PAYLOAD

我需要檢查 header 文件是否包含兩個屬性,如果存在,則該文件應與其 PAYLOAD 文件一起移動到另一個目錄。 我正在使用 xmllint --xpath 來檢查屬性,它有一個headers標簽,里面是一堆header標簽,我的查詢:

xmllint --xpath "boolean(//*[local-name()='headers' and *[local-name()='header'][@name='Type' and @value='AAAA'] and *[local-name()='header'][@name='Update' and @value='DONE']])

xpath 查詢工作正常,並根據屬性是否存在返回真/假。 問題在於如何僅迭代 header 文件並移動它們。 我嘗試使用 find :

#!/bin/bash
dest="/tmp/proc"
loc="/tmp/files"
find $loc -maxdepth 1 -mindepth 1 ! -name '*_PAYLOAD' -exec xmllint --xpath "boolean(//*[local-name()='headers' and *[local-name()='header'][@name='Type' and @value='AAAA'] and *[local-name()='header'][@name='Update' and @value='DONE']]) " {} \; -exec mv {} $dest \; -exec mv {}_PAYLOAD $dest \;

但是,即使我的 xpath 查詢返回 false,此查詢也會移動文件,我認為 find -exec 可能會將 true/false 作為字符串返回,因此為 true,並且仍繼續執行下一個 exec。 所以我嘗試使用 sh -c 查找,這樣我就可以合並某種 if 和 else 結構:

    #!/bin/bash
    dest="/tmp/proc"
    loc="/tmp/files"
    find $loc -maxdepth 1 -mindepth 1 ! -name '*_PAYLOAD' -exec sh -c '
        for file do
        stat=$(xmllint --xpath "boolean(//*[local-name()='headers' and *[local-name()='header'][@name='Type' and @value='AAAA'] and *[local-name()='header'][@name='Update' and @value='DONE']]) " "$file" | grep 'true' | wc -l)
        if [ "$stat" -eq 1 ]
            mv "$file" "$dest"
            mv "$file"_PAYLOAD "$dest"
    done' sh {} \;

但這給出了一個錯誤:

sh: -c: line 6: syntax error near unexpected token `done' sh: -c: line 6: `done'

我從https://unix.stackexchange.com/questions/321697/why-is-looping-over-finds-output-bad-practice/321753#321753看到的這個語法

也許您可以在下面嘗試,請檢查這是否適合您:

#!/bin/bash
    dest="/tmp/proc"
    loc="/tmp/files"
    for i in $(find "$loc" -maxdepth 1 -mindepth 1 ! -name "*_PAYLOAD" -exec basename "{}" \;)
    do
        stat=$(xmllint --xpath "boolean(//*[local-name()='headers' and *[local-name()='header'][@name='Type' and @value='AAAA'] and *[local-name()='header'][@name='Update' and @value='DONE']]) "$i"
      if [[ "$stat" == "true" ]]
        then
          mv "$i" "$dest"
          mv "$i"_PAYLOAD "$dest"
      fi
    done

    

已編輯

另一種看法——
xmllint顯然沒有返回 boolean 作為其退出代碼,而且丑陋得要命,所以我將它轉嫁給了 function。

tst() { xmllint --xpath "boolean(//*[local-name()='headers' and *[local-name()='header'][@name='Type' and @value='AAAA'] and *[local-name()='header'][@name='Update' and @value='DONE']])" "$1"; }

for p in /tmp/files/*_PAYLOAD
do f=${p%_PAYLOAD}
   [[ -e "$f" && true == "$(tst $f)" ]] && mv $f $p /tmp/proc
done

通過使用 (及其集成的EXPath File Module )而不是xmllint相信根本不需要 Bash 腳本。

xidel -s --xquery '
  let $dest:="/tmp/proc/",
      $loc:="/tmp/files/"
  for $x in file:list($loc,false(),"*_PAYLOAD")
  where doc($loc||$x)//*[
    local-name()="headers" and
    *[local-name()="header"][@name="Type" and @value="AAAA"] and
    *[local-name()="header"][@name="Update" and @value="DONE"]
  ]
  return
  file:move($loc||$x,$dest||$x)
'

暫無
暫無

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

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