bash脚本导航目录子结构,然后对.xml文件进行操作

时间:2015-04-12 10:31:51

标签: linux bash io directory-structure

我厌倦了这个:

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以及0203等等...

然后在01内再次010203,......

在每个终端目录中都有许多我想要应用脚本的.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之外,我还有20062005,所以我想要做的就是运行一次并让程序自己导航该结构。

我迄今为止的尝试都没有成功,或许你们中间有人会知道如何实现这一目标?

感谢您的考虑。

更新

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

2 个答案:

答案 0 :(得分:2)

我会使用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

答案 1 :(得分:1)

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