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

Far*_*ane 0 bash shell

我正在尝试遍历文件夹中的文件并测试.txt扩展名。但是我收到以下错误:“ awk:无法打开=(没有这样的文件或目录)

这是我的代码:

!/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;
Run Code Online (Sandbox Code Playgroud)

Ini*_*ian 6

您执行此操作的方式在许多方面都是错误的。

  1. 您永远不应解析的输出ls。它不能直观地处理包含特殊字符的文件名请参阅为什么不应该解析ls(1)的输出
  2. 不要使用变量来存储多行数据。lsin变量的输出应进行分词。在您的情况下,files将其作为普通变量进行引用,并且没有设置分隔符,则无法浏览存储的多个文件。
  3. 使用awk是完全没有必要在这里,部分$file | awk -F . "{ print $NF }" = txt是完全错误的,你是不是合格的名称file来管,只是变量$file,它应该是echo "$file"
  4. #!/bin/bash如果您打算将其作为可执行文件(即)运行,则应该在脚本中设置正确的解释器she-bang ./script.sh。推荐的方法是#!/usr/bin/env bash让外壳识别bash已安装的默认版本。

因此,您的要求可以简单地简化为

for file in *.txt; do
    [ -f "$file" ] || continue
    echo "$file"
done
Run Code Online (Sandbox Code Playgroud)

这是使用glob模式的简单示例,使用glob模式*.txt对以该txt格式结尾的所有文件进行路径名扩展。循环处理之前,水珠被扩展为文件列表,即假设该文件夹有文件作为1.txt2.txt并且foo.txt,环路产生

for file in 1.txt 2.txt foo.txt; do
Run Code Online (Sandbox Code Playgroud)

即使没有文件存在,即当glob匹配为空(找不到文本文件)时,该条件[ -f "$file" ] || continue也可以通过检查glob是否返回任何有效的文件结果还是仅返回未扩展的字符串来确保正常退出循环。[ -f "$file" ]如果有效的文件参数除外,则该条件将对所有内容均失败。

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

shopt -s nullglob
for file in *.txt; do
    echo "$file"
done
Run Code Online (Sandbox Code Playgroud)

另一种使用shell数组存储glob结果并稍后解析它们以对它们执行特定操作的方法。在将文件列表作为另一个命令的参数列表时,这种方法很有用。使用适当的带引号的扩展"${filesList[@]}"名将保留文件名中的空格/制表符/换行符和其他元字符。

shopt -s nullglob
filesList=(*.txt)

for file in "${filesList[@]}"; do
    echo "$file"
done
Run Code Online (Sandbox Code Playgroud)