循环浏览bash中扩展名为.txt的所有文件

循环浏览bash中扩展名为.txt的所有文件,bash,shell,Bash,Shell,我正在尝试循环文件夹中的文件并测试.txt扩展名。 但是我得到了以下错误:“awk:cannotopen=(没有这样的文件或目录) 这是我的密码: !/bin/bash files=$(ls); for file in $files do # extension=$($file | awk -F . '{ print $NF }'); if [ $file | awk -F . "{ print $NF }" = txt ] then echo $file;

我正在尝试循环文件夹中的文件并测试.txt扩展名。 但是我得到了以下错误:“awk:cannotopen=(没有这样的文件或目录)

这是我的密码:

!/bin/bash

files=$(ls);
for file in $files
  do
  # extension=$($file | awk -F . '{ print $NF }');
  if [ $file | awk -F . "{ print $NF }" = txt ]
    then
      echo $file;
    else
      echo "Not a .txt file";
  fi;
done;

你这样做在很多方面都是错误的

  • 永远不要解析
    ls
    的输出。它不会处理包含特殊字符的文件名
  • 不要使用变量存储多行数据。变量中
    ls
    的输出应进行分词。在您的情况下,
    files
    被引用为普通变量,如果没有分隔符集,则无法浏览存储的多个文件
  • 这里绝对不需要使用
    awk
    ,部分
    $file | awk-F.{print$NF}”=txt
    是完全错误的,您没有将
    文件的名称
    传递给管道,只是变量
    $file
    ,它应该是
    echo“$file”
  • 如果您计划将其作为可执行文件运行,即
    /script.sh
    ,那么脚本中正确的解释器she bang应该设置为
    !/bin/bash
    。更推荐的方法是说
    !/usr/bin/env bash
    ,让shell识别安装的
    bash
    的默认版本
  • 因此,您的要求可以简化为

    for file in *.txt; do
        [ -f "$file" ] || continue
        echo "$file"
    done
    
    这是一个使用glob模式的简单示例,该模式使用
    *.txt
    对所有以
    txt
    格式结尾的文件进行路径名扩展。在处理循环之前,glob被扩展为文件列表,即假设文件夹中的文件为
    1.txt
    2.txt
    foo.txt
    ,循环生成到

    for file in 1.txt 2.txt foo.txt; do
    
    即使在没有文件的情况下,即当glob匹配为空(没有找到文本文件),条件
    [-f“$file”]| | continue
    也会通过检查glob是否返回任何有效的文件结果或只是未展开的字符串来确保循环正常退出。条件
    [-f“$file”]
    如果没有有效的文件参数,则所有操作都将失败

    或者,如果您再次针对bourne shell的脚本,请启用glob选项以删除不匹配的glob,而不是保留它们

    shopt -s nullglob
    for file in *.txt; do
        echo "$file"
    done
    
    另一种方法是使用shell数组存储全局结果,并在以后对其进行解析以对其执行特定操作。当将文件列表作为另一个命令的参数列表时,这种方法非常有用。使用正确的带引号的扩展名
    “${filelist[@]}“
    将保留文件名中的间距/制表符/换行符和其他元字符

    shopt -s nullglob
    filesList=(*.txt)
    
    for file in "${filesList[@]}"; do
        echo "$file"
    done
    

    你这样做在很多方面都是错误的

  • 永远不要分析
    ls
    的输出。直观地看,它不会处理包含特殊字符的文件名
  • 不要使用变量来存储多行数据。变量中
    ls
    的输出应进行分词。在您的情况下,
    文件
    被作为普通变量引用,如果没有分隔符集,您将无法浏览存储的多个文件
  • 这里绝对不需要使用
    awk
    ,部分
    $file | awk-F。“{print$NF}”=txt
    完全错误,您没有将
    文件的名称
    传递给管道,只是变量
    $file
    ,它应该是
    echo“$file”
  • 正确的解释器应该设置为
    #/如果您计划将其作为可执行文件运行,即
    /script.sh
    ,请在脚本中输入bin/bash
    。更推荐的方法是说
    #/usr/bin/env bash
    ,让shell识别安装的
    bash
    的默认版本
  • 因此,您的要求可以简化为

    for file in *.txt; do
        [ -f "$file" ] || continue
        echo "$file"
    done
    
    这是一个使用glob模式的简单示例,它使用
    *.txt
    对所有以
    txt
    格式结尾的文件进行路径名扩展。在处理循环之前,glob将展开为文件列表,即假设文件夹中的文件为
    1.txt
    2.txt
    foo.txt
    ,循环将生成为

    for file in 1.txt 2.txt foo.txt; do
    
    即使在不存在文件的情况下,即当glob匹配为空(未找到文本文件),条件
    [-f“$file”]| | continue
    也会通过检查glob是否返回任何有效的文件结果或只是未展开的字符串来确保循环正常退出。条件
    [-f“$file”]
    在除有效的文件参数外的所有情况下都将失败

    或者,如果您再次针对bourne shell的脚本,请启用glob选项以删除不匹配的glob,而不是保留它们

    shopt -s nullglob
    for file in *.txt; do
        echo "$file"
    done
    
    另一种方法是使用shell数组存储glob结果,并在以后对其进行解析以对其执行特定操作。当将文件列表作为另一个命令的参数列表时,这种方法非常有用。使用正确的带引号的扩展名“${filesList[@]}”将保留文件名中的间距/制表符/换行符和其他元字符

    shopt -s nullglob
    filesList=(*.txt)
    
    for file in "${filesList[@]}"; do
        echo "$file"
    done
    

    你不能在*.txt中为i使用globbing和
    ;做完成
    ?@oliv,但首先我必须列出我所在文件夹中的所有文件?对吗?@oliv,你的解决方案有效。谢谢你,你不能在*.txt中为i使用globbing和
    ;做完成
    ?@oliv,但首先我必须列出我所在文件夹中的所有文件?对吗?@oliv,你的解决方案有效。非常感谢。