如何在“for”函数中使用空格

如何在“for”函数中使用空格

问题是我正在为课堂编写一个脚本,问题是“编写一个脚本,命名实际目录中的所有文件并告诉我们它们的名称和权限”,因此我编写了以下脚本:

#!/bin/bash

for name in `ls -l . | awk {print'$9'}`
do
echo "The file $name has the following permissions: `ls -l . | grep $name | cut -d" " -f1`"
done

好的,脚本在某种程度上可以工作,但问题是它不会显示列表中的所有文件,ls -l因为我正在打印9th column(文件的名称),但如果它有一个空格,空格后的单词是column 10,所以我尝试这样做:

#!/bin/bash

for name in `ls -l . | awk {print'$9,$10'}`
do
echo "The file $name has the following permissions: `ls -l . | grep $name | cut -d" " -f1`"
done

但是当我这样做时,问题是变量 $name 将把第一列和第二列作为单独的单词引用,并且它将显示它们,就好像它们是不同的文件一样。

ls我也尝试过在使用时转义空格ls -lb,但是这样grep命令就不起作用了,如果我使用 grep '$name\s'它,它会直接复制 $name\s,所以它不会在ls命令中搜索任何内容...

解决这个问题可能真的很容易,但我已经研究了 5 个多小时却没有任何进展... 任何帮助都非常感谢!

答案1

不要解析ls! 相反,使用全局

for name in ./*; do

您还可以使用其他方法改进脚本。

  1. 在循环中,同样不要解析ls。而是使用stat直接获取权限。1
  2. 使用较新的命令替换语法,$(...)而不是已弃用的反引号`...`
  3. 定义一个变量$perms,使打印字符串更清晰、更易读。

所以:

for name in ./*; do
    perms="$(stat -c "%A" "$name")"
    echo "The file $name has the following permissions: $perms"
done

脚注:

  1. 如果stat不存在,并且您必须从获取权限ls,则可以将文件名作为参数提供给它,并使用该-d标志,以便它不会进入目录或取消引用符号链接。

    ls -ld "$name" | cut -d" " -f1
    

    但同样,您不应该解析ls。如果任何文件名包含换行符,则此方法会失败。

答案2

写这样的东西绝对不是一个好主意

for stuff in `ls`; ...

ls解析is的输出一个非常糟糕的主意因为的输出ls只是文本,并且不能可靠地表示文件的实际名称。

处理文件使用 shell globs反而。

for stuff in *; ...

*您可以使用而不是./*,其含义相同,但更安全,因为所有路径都以./(当前目录)开头,而不是以文件名开头的任何可疑符号开头,后者可能会导致 shell 执行扩展(例如~)(尽管您绝对应该“引用”您的变量以防止这种不必要的 shell 扩展)或您尝试使用的命令可能会尝试特殊解释的符号(例如-)。您也可以使用*而不是,但在循环中运行的命令的所有选项之后./*添加,以防止以 开头的文件名被解释为选项。这样会给出一个干净的路径,但如果您想使用,有时可以使用 in 命令或其他技巧清理路径。请注意,并非所有命令都支持指示选项的结束。---./*"$(basename $var)"--

不要尝试解析您想要的内容ls -l,而是使用专门用于显示文件元数据的命令并仅询问您想要的输出。

stat -c "%n %A" file

应该能满足您的要求。如果您想显示一条消息,只需将其写入即可:)

以下是我的做法:

for file in *; do stat -c 'The permissions of %n are: %A' -- "$file"; done

相关内容