[英]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'
也許您可以在下面嘗試,請檢查這是否適合您:
#!/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
通過使用xidel (及其集成的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.