2012-08-12 119 views
0

我有两个文件夹,里面装满了培训和相应的测试文件,我想用shell脚本运行配对对方。Shell脚本:截断字符串

这是我到目前为止有:

for x in SpanishLS.train/*.train 
do 
    timbl -f $x -t SpanishLS.test/$x.test 
done 

这应该采取file1(-n).train在一个目录下,在其他寻找file1(-n).test,并运行它们低谷名为timbl工具。 它所做的是找一个名为SpanishLS.train/file1(-n).train.test的文件,这当然不存在。 我试图做的,无济于事,截断$x的方式,让脚本找到正确的文件,但每当我这样做,$x被截断的方式太早,导致脚本甚至找不到.train文件。

我该如何编码?

回答

2

使用basename

for x in SpanishLS.train/*.train 
do 
    timbl -f $x -t SpanishLS.test/$(basename "$x" .train).test 
done 

即删除该目录前缀,从$x.train后缀,并建立所需要的名字。

bash(和其他POSIX-compliant shells),你可以用两个壳parameter expansionsbasename操作,而不调用外部程序。 (我不认为有一种方法将两个扩展合二为一。)

for x in SpanishLS.train/*.train 
do 
    y=${x##*/}          # Remove path prefix 
    timbl -f $x -t SpanishLS.test/${y%.train}.test # Remove .train suffix 
done 

当心:bash支持相当多的不是由POSIX定义的(有用的)扩展。例如,${y//.train/.test}bash-只是表示法(或bash和兼容的shell表示法)。

+0

的换人不仅猛砸,但是POSIX SH ,不是吗? – tripleee 2012-08-12 18:07:07

+0

@tripleee嗯......是的,'##'和'%'(和'#'和'%%')扩展在[POSIX shell]中(http://pubs.opengroup.org/onlinepubs/9699919799 /utilities/V3_chap02.html#tag_18_06_02)。其他地方的评论建议'$ {x //。train/.test}';这不是POSIX扩展。我已经更新了我的答案 - 感谢您指出了这一点。 – 2012-08-12 18:09:53

+0

谢谢!这比我想象的更加优雅! – lhausmann 2012-08-12 18:28:24

0

在文件名替换的.train所有出现到.text

timbl -f $x -t $(echo $x | sed 's/\.train/.text/g') 
+0

可以在bash中执行此操作:'-t $ {x //。train/.test}' – 2012-08-12 18:03:44

+0

这不涉及'SpanishLS.train'和'SpanishLS.test'路径前缀。 – 2012-08-12 18:06:38

4

如果我给你的权利,这将做的工作:

for x in SpanishLS.train/*.train 
do 
    y=${x##*/} # strip basepath 
    y=${y%.*} # strip extention 
    timbl -f $x -t SpanishLS.test/$y.test 
done