【问题标题】:Filter directory listing with shell script使用 shell 脚本过滤目录列表
【发布时间】:2010-10-12 07:54:44
【问题描述】:

如果我有一个 BASH 变量:

Exclude="somefile.txt anotherfile.txt"

如何获取目录的内容,但将上述内容排除在列表中的文件中?我希望能够做类似的事情:

Files=  #some command here
someprogram ${Files}

someprogram 应该被赋予特定目录中的所有文件,${Exclude} 变量中的文件除外。不能修改someprogram

【问题讨论】:

  • 我可以使用sedfindgrep 来设想多种简单便携的解决方案,但不确定是否值得再弄清楚它们是否值得^^

标签: bash shell


【解决方案1】:

您可以使用查找。类似:

FILES=`find /tmp/my_directory -type f -maxdepth 1 -name "*.txt" -not -name somefile.txt -not -name anotherfile.txt`

其中 /tmp/my_directory 是您要搜索的路径。

如果你想要一个简单的 for 循环,你可以从排除中建立“-not -name blah -not -name blah2”列表...

【讨论】:

  • find 是否可以跨主要的类 Unix 平台移植? BSD、Linux等
  • 取决于使用的标志,但该命令中的标志似乎是标准的
【解决方案2】:

我不确定您是否正在学习 unix shell 脚本,但这里是 bash 的一个工作示例:

#!/bin/bash

Exclude=("a" "b" "c")
Listing=(`ls -1Q`)

Files=( $(comm -23 <( printf "%s\n" "${Listing[@]}" ) <( printf "%s\n" "${Exclude[@]}"
) ) )

echo ${Files[@]}

请注意,我将 Exclude 中的每个文件名都用双引号括起来并添加了 他们周围的括号。将echo替换为someprogram,更改ls命令 到你想检查的目录,你应该让它工作。 comm 程序是关键,在这里。

【讨论】:

  • 这似乎是最简单的解决方案,因为它不需要循环。
【解决方案3】:

这是标准 Unix 命令行的单行代码:

ls | grep -v "^${排除}$" | xargs

它确实有一个假设。 ${Exclude} 需要正确转义,这样句号之类的字符就不会被解释为正则表达式的一部分。

【讨论】:

  • 如果我只有一个我想排除的文件,这将起作用,但我最多可以有 10 个(但我不想对排除的文件设置任何限制)。
  • @dreamlax Nope: PATTERNS is one or more patterns separated by newline characters 你可以给多个模式;)
【解决方案4】:

假设文件名没有空格或其他病态字符:

shopt -s extglob
Files=(!(@(${Exclude// /|})))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 2016-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    相关资源
    最近更新 更多