2017-10-01 77 views
0

我是shell脚本的新手。我想迭代一个目录下面的特定模式。KSH Shell脚本匹配文件模式

Ad_sf_03041500000.dat 
SF_AD_0304150.DEL 
SF_AD_0404141.EXP 

位数应与此模式完全匹配。 我正在使用KSH shell脚本。你能不能帮我迭代循环中的文件?

+1

你能否让我知道哪种模式应该与文件名匹配?应该预期输出什么?你想要一个目录中的特定文件,或者你想看所有的文件? – RavinderSingh13

+0

你说“*位数应该与这个模式*完全匹配”,但是你的第一个例子的位数与你的第二个和第三个不同。请准确地描述*有多少个字母,多少个数字以及哪些“扩展”是有效的。情况如何,这是否意义重大? – cdarke

+0

感谢您的支持我的朋友。我的文件模式是ad_sf_11digits.dat和SF_AD_7digits.EXP和SF_AD_7digits.DEL ..我给出的数字是样本。我需要.dat文件在最后一个下划线后应该有正好11位数字,而其他两个文件在最后一个下划线后应该只有7位数字 – Mani

回答

0

自动通配符生成方法。与领先的文本和行号打印文件名...

  1. POSIX外壳:

    2> /dev/null find \ 
        $(echo Ad_sf_03041500000.dat SF_AD_0304150.DEL SF_AD_0404141.EXP | 
        sed 's/[0-9]/[0-9]/g') | 
    while read f ; do 
        echo "Here's $f"; 
    done | nl 
    
  2. ksh(从Chepner借了点):

    set - Ad_sf_03041500000.dat SF_AD_0304150.DEL SF_AD_0404141.EXP 
    for f in ${*//[0-9]/[0-9]} ; do [ -f "$f" ] || continue 
        echo "Here's $f"; 
    done | nl 
    

任一方法的输出:

 1 Here's Ad_sf_03041500000.dat 
    2 Here's SF_AD_0304150.DEL 
    3 Here's SF_AD_0404141.EXP 

如果不需要行号,请省略| nlecho可以替换为需要在文件上运行的任何命令。


POSIX代码如何工作。 OP规范很简单,只需稍微调整即可生成正确的通配符。例如:

echo Ad_sf_03041500000.dat SF_AD_0304150.DEL SF_AD_0404141.EXP | 
sed 's/[0-9]/[0-9]/g' 

其输出恰好所需的图案(线添加为清楚起见供稿):

Ad_sf_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].dat 
SF_AD_[0-9][0-9][0-9][0-9][0-9][0-9][0-9].DEL 
SF_AD_[0-9][0-9][0-9][0-9][0-9][0-9][0-9].EXP 

的图案上面去find,打印只有匹配的文件名,(未图案自身时没有文件),然后文件名转到while循环。

(该ksh变种是同样的方法,但使用代替sedfind模式替换settest -f

+0

最有可能的OP意味着更抽象的模式,但固定的字符串也是一种模式。 – agc

+0

感谢您的支持,我的朋友@agc。我想你错误地理解了我的问题。我的文件模式是ad_sf_11digits.dat和SF_AD_7digits.EXP和SF_AD_7digits.DEL ..我给出的数字是样本。我需要.dat文件应该有最后一个下划线后的正好11位数字,其他两个文件应该只有最后一个下划线后的7位数字 – Mani

0

你正在寻找的模式是

Ad_sf_{11}([[:digit:]]).dat 
SF_AD_{7}([[:digit:]]).DEL 
SF_AD_{7}([[:digit:]]).EXP 

{n}(...)模式与以下模式完全匹配nksh的唯一扩展(据我所知,甚至不是zsh提供了一个等价物)。

遍历匹配的文件,你可以使用

for f in Ad_sf_{11}(\d).dat SF_AD_{7}(\d)[email protected](DEL|EXP); do 

在那里我已经用“挑人”运营商@(...)到两个较短的图案组合成一个单一的模式,我用\d,其中ksh在圆括号内支持作为[[:digit:]]的较短版本。

+0

* Lubuntu v17.04 *,测试上述代码在'mksh',返回:'语法错误: '''unexpected'。在'ksh'中测试时,循环中的echo $ f会在文件不存在时自动打印模式 - 可能是需要的,但它可能不是... – agc

+2

'mksh'是“与ksh基本兼容”的,但它不是'ksh',这就是OP声称使用的内容。至于没有匹配发生时会发生什么,这在文件名生成的手册页中清楚地记录:“如果否找到与该模式相匹配的文件名,那么该文件名的组成部分 保持不变,除非该模式的前缀为〜(N),在这种情况下,它将按照下面的描述删除。“ – chepner

+0

标准方法是检查是否存在”f '实际上是一个位于循环顶部的文件:'[ -f“$ f”] || continue'。 – chepner