bash 脚本导航目录子结构,然后对 .xml 文件进行操作
Posted
技术标签:
【中文标题】bash 脚本导航目录子结构,然后对 .xml 文件进行操作【英文标题】:bash script to navigate directory substructure and then operate on .xml files 【发布时间】:2015-04-12 10:31:51 【问题描述】:我厌倦了这个:
for dir in /home/matthias/Workbench/SUTD/nytimes_corpus/NYTimesCorpus/2007/02/*/
for f in *.xml ; do
echo $f | grep -q '_output\.xml$' && continue # skip output files
g="$(basename $f .xml)_output.xml"
java -mx600m -cp /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/stanford-ner-3.5.1.jar edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz -textFile $f -outputFormat inlineXML > $g
done
done
这是基于对this question 的回答,但这不起作用。
我有一个文件夹结构,这样在目录NYTimesCorpus
中有一个目录2007
,在里面有一个目录01
,还有02
、03
,等等......
然后在01
内又有01
,02
,03
,...
在这些终端目录中的每一个中都有许多我想要应用脚本的 .xml 文件:
for f in *.xml ; do
echo $f | grep -q '_output\.xml$' && continue # skip output files
g="$(basename $f .xml)_output.xml"
java -mx600m -cp /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/stanford-ner-3.5.1.jar edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz -textFile $f -outputFormat inlineXML > $g
done
但是有这么多不同的目录,在每个目录中运行它是一种罕见的折磨。除了2007
,我还有2006
和2005
,所以理想情况下我想做的就是运行它一次,然后让程序自行导航该结构。
到目前为止,我的尝试还没有成功,也许你们中的某个人知道如何实现这一目标?
感谢您的考虑。
更新
textFile=./scrypt.sh
outputFormat=inlineXML
Loading classifier from /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz ... done [2.2 sec].
CRFClassifier tagged 71 words in 5 documents at 959.46 words per second.
CRFClassifier invoked on Sun Apr 12 19:33:34 HKT 2015 with arguments:
-loadClassifier /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz -textFile ./scrypt.sh -outputFormat inlineXML
loadClassifier=/home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz
【问题讨论】:
【参考方案1】:我会使用find
,因为它递归地工作:
find /path/to/xmls -type f ! -name '*_output.xml' -name '*.xml' -exec ./script.sh \;
为了更好的可读性,我会将应该对每个文件执行的操作保存到script.sh
:
#!/bin/bash
f="$1"
g="$f%%.*_output.xml"
java -mx600m -cp /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/stanford-ner-3.5.1.jar edu.stanford.nlp.ie.crf.CRFClassifier -loadClassifier /home/matthias/Workbench/SUTD/nytimes_corpus/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz -textFile "$f" -outputFormat inlineXML > "$g"
并使其可执行:
chmod +x script.sh
【讨论】:
所以在 /path/to/xmls 我必须指定每个目录吗? 所以/path/to/xmls
可以只是相对的根目录,即/home/matthias/Workbench/SUTD/nytimes_corpus/
是吗?
是的,在您的示例中,这应该是正确的路径
我刚试过,但没有用。我收到了错误Exception in thread main edu.stanford.nlp.io.RuntimeIOException: java.io.FileNotFoundException: *.xml (No such file or directory)
find /path/to/xmls -type f -name '*.xml'
的输出是什么?【参考方案2】:
find
是一个很好的解决方案。听起来所有的 xml 文件都在相同的目录深度,所以试试这个:
dir=/home/matthias/Workbench/SUTD/nytimes_corpus
for f in $dir/NYTimesCorpus/*/*/*/*.xml; do
[[ $f == *_output.xml ]] && continue # skip output files
g="$f%.xml_output.xml"
java -mx600m \
-cp $dir/NER/stanford-ner-2015-01-30/stanford-ner-3.5.1.jar \
edu.stanford.nlp.ie.crf.CRFClassifier \
-loadClassifier $dir/NER/stanford-ner-2015-01-30/classifiers/english.all.3class.distsim.crf.ser.gz \
-textFile "$f" \
-outputFormat inlineXML > "$g"
done
glob 模式$dir/NYTimesCorpus/*/*/*/*.xml
指定所需的 xml 文件恰好低于 NYTimesCorpus 3 级。那是错误的深度,然后更改模式中*/
的数量。
如果 xml 文件可以出现在不同的深度,请使用 find
,或在 bash 中使用:
shopt -s globstar nullglob
for f in $dir/NYTimesCorpus/**/*.xml; do
reference
【讨论】:
好的,首先让我说:好极了。绝对名列前茅。极好的。先生,向你致敬这个非凡的解决方案。然后跟进,在其他人没有的情况下,这个工作的机制是什么?这怎么可能改变以适应稍微不同的深度?以上是关于bash 脚本导航目录子结构,然后对 .xml 文件进行操作的主要内容,如果未能解决你的问题,请参考以下文章
Bash 脚本检测我的 USB 何时插入,然后将其与目录同步