【问题标题】:Bash-scripting, usage of the 'for' loopBash 脚本,“for”循环的使用
【发布时间】:2013-11-07 13:04:29
【问题描述】:

我正在尝试编写一个显示文件内容的简单 bash 脚本。

#!/bin/bash

echo 'Input the path of a file or directory...'
read File

if [ -e $File ] && [ -f $File ] && [ -r $File ]
    then
    echo 'Displaying the contents of the file '$File
    cat $File


elif [ -d $File ] && [ -r $File ]
then
echo 'Displaying the contents of the directory '$File       
    for FILE in `ls -R $File`
        do
               cd $File/$FILE
               echo 'Displaying the contents of the file '$FILE
               cat $FILE
        done

else 
echo 'Oops... Cannot read file or directory !'
fi

用户应输入文件或目录路径。如果用户输入一个文件,程序会用 cat 显示它。如果用户输入一个目录,它应该显示所有文件的内容,包括子目录中的文件。程序的那部分运行得不是很好。我想得到一个不显示错误的结果,例如“没有这样的文件或目录”,而只显示文件的内容。你能帮助我吗 ? 提前致谢。

【问题讨论】:

标签: bash shell loops for-loop scripting


【解决方案1】:

ls -R 是在所有子目录中查找所有文件的错误工具。 find 是更好的选择:

echo "displaying all files under $File"
find "$File" -type f -printf "Displaying contents of %p\n" -exec cat {} \;

【讨论】:

  • 感谢您的回复!代码工作正常,但有没有办法在显示文件内容之前打印文件名?
  • … -exec echo {}; cat {} \;
  • 感谢 chepner,但我得到 '' find: missing argument to `-exec' ''。
  • ... -exec echo "文件名:{}" \; -执行猫 {} \; --- 编辑答案
  • 不要使用-exec echo ...,这很愚蠢。请改用-printf "Displaying contents of %p\n"(或%f)。
【解决方案2】:

find 命令将为您节省大量逻辑:

#!/bin/bash 

echo 'Input the path of a file or directory...'
read File
DirName="."

if  echo $File | grep '/' ;  then
  DirName=$(dirname $File)
  File=$(basename $File)
fi

find "$DirName" -type f -name "$File" -exec cat {} \;
find "$DirName" -type d -name "$File" -exec ls {} 

第一次查找将查找所有名为 $File 的“常规”(-type f)文件并将它们分类 第二个查找将查找所有“目录”(-type d)并列出它们。

如果他们没有找到,那么 -exec 部分将不会执行。 grep 将分割路径,如果那里有斜线。

【讨论】:

  • 感谢您的回复!当我尝试运行您的脚本时,我收到一个错误“查找:警告:Unix 文件名通常不包含斜杠...”。
  • 为了解决这个问题,您可以使用 basename 和 dirname 例如拆分名称查找 $(dirname $File) -name "$(basename $File)"
【解决方案3】:

你可以打印当前目录下的所有文件

for f in * do
    cat $f;
done

【讨论】:

  • 是的,但在 for 循环中,他可以轻松添加其他命令(例如他拥有的“调试”回显)。我只是给了他结构。为什么错了?
  • 你是对的,循环允许更大的灵活性。主要问题是 for 循环是错误的方法。 OP 使用ls -R,这显然意味着需要子目录。他的循环和你的循环都不能正确处理这种情况。 find是要走的路。
  • 感谢您的回复!
  • 您可以使用shopt -s nullglob globstar; for subdir in **/*/ 进行递归,但是分离出文件和目录会变得乏味。 find 如果你只是想 cat 文件肯定更容易。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-31
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
相关资源
最近更新 更多