Bash:循环遍历与扩展名不匹配的文件

时间:2016-05-16 16:24:35

标签: regex bash file loops

我正在编写一个bash脚本,需要在目录中循环与特定扩展名不匹配的文件。到目前为止,我发现以下代码循环所有与给定扩展名匹配的文件:

for f in *.txt ; do
    echo $f;
done

insthead如何循环遍历与指定扩展名不匹配的文件?

6 个答案:

答案 0 :(得分:5)

  

循环目录中与特定扩展名不匹配的文件

您可以使用extglob

shopt -s extglob

for f in *.!(txt); do
    echo "$f"
done

模式*.!(txt)将匹配所有带点的条目,并且点后面没有txt

编辑:请参阅以下评论。这是一个find版本,用于循环显示当前目录中与特定扩展名不匹配的文件:

while IFS= read -d '' -r f; do
    echo "$f"
done < <(find . -maxdepth 1 -type f -not -name '*.txt' -print0)

答案 1 :(得分:5)

您可以与==运算符进行模式匹配。

for f in *; do
    [[ $f == *.txt ]] && continue
    # [[ $f != *.txt ]] || continue
    ...
done

如果这可能在空目录中运行,请在循环之前使用shopt -s nullglob,或将[ -e "$f" ] || continue放在循环中。 (前者更可取,因为它可以避免不断检查文件是否存在。)

答案 2 :(得分:1)

待办事项

find /path/to/look -type f -not -name "*.txt" -print0 | while read -r -d '' file_name
do
echo "$file_name"
done

当您的文件名可能不标准时。

注意:

如果您不希望递归搜索子文件夹中的文件,请在-maxdepth 1之前添加-type f

答案 3 :(得分:1)

这样做:

shopt -s extglob
for f in !(*.txt) ; do
    echo $f
done

您只需使用!(glob_pat)反转glob模式,并使用它,您需要启用扩展的glob。

如果要忽略目录,则:

shopt -s extglob
for f in !(*.txt) ; do
    [ -d "$f" ] && continue   # This will ignore dirs
    # [ -f "$f" ] && continue # This will ignore files
    echo $f
done

如果你想进入所有子目录,那么:

shopt -s extglob globstar
for f in !(*.txt) **/!(*.txt) ; do
    [ -d "$f" ] && continue   # This will ignore dirs
    # [ -f "$f" ] && continue # This will ignore files
    echo $f
done

答案 4 :(得分:0)

如果您对GNU解决方案没问题,请试试这个:

for f in $(find . -maxdepth 1 -type f \! -name \*.txt) ; do
  printf "%s\n" "${f}"
done

如果文件名中包含特殊字符,例如(空格),则会中断。

对于安全的内容,仍然是GNU,请尝试:

find . -maxdepth 1 -type f \! -name \*.txt -printf "%p\0" | xargs -0 sh -c '
    for f ; do
      printf "%s\n" "${f}"
    done' arg0

答案 5 :(得分:-1)

for f in $(ls --hide="*.txt")
do
    echo $f
done