【问题标题】:Basename puts single quotes around variableBasename 在变量周围加上单引号
【发布时间】:2012-07-29 01:08:09
【问题描述】:

我正在编写一个简单的 shell 脚本来进行自动备份,我正在尝试使用 basename 创建一个目录列表,然后他们解析这个列表以获取列表中的第一个和最后一个目录。

问题是:当我在终端中使用 basename 时,一切正常,它给了我想要的列表。例如:

basename -a /var/*/ 

给我一​​个 /var 中所有目录的列表,名称末尾不带 /,每行一个。 但是,当我在脚本中使用它并将变量传递给 basename 时,它​​会在变量周围加上单引号:

while read line; do
dir_name=$(echo $line)
basename -a $dir_name/*/ > dir_list.tmp
done < file_with_list.txt

使用 +x 运行时:

+ basename -a '/Volumes/OUTROS/backup/test/*/'

因此,结果不是我需要的。

现在,我知道一定有上千种方法可以解决基本名称问题,但是我什么也学不到,对吧? ;)

如何去掉单引号? 如果我的目录名称中有空格?

【问题讨论】:

  • 跟踪输出有些随意,只是为了向您展示执行了哪些命令。如果您在dir_list.tmp 中得到正确的输出,我就不用担心了。 (当然,如果dir_list.tmp 的内容不是你想要的,你应该发布你得到的和你期望的。)仅供参考,dir_name="$line" 就足够了。
  • 仅供参考:basename-a-s 选项不是 POSIX 强制的,因此不是通用的。当您的脚本仅在 Mac OS X 上运行时,这不是问题,但可能是可移植性问题。
  • file_with_list.txt 的内容是什么?您编写的代码的更大上下文是什么? (也就是说,你到底想做什么?)这看起来很接近ParsingLS problem
  • @chepner 不,我没有得到正确的输出。在控制台中,我得到了我想要的列表。运行脚本时,我只得到一个 * 作为文件的内容,这正是我在运行带有单引号的命令时得到的:(
  • @JonathanLeffler 感谢您的信息。我也打算在 Linux 中使用相同的脚本。所以我想我会放弃基本名称。

标签: macos bash quotes


【解决方案1】:

如果您的目录名称可能包含空格,则需要引用 dir_name 的值(这对于任何变量扩展都是一个好主意,无论您是否需要空格)。

while read line; do
  dir_name=$line
  basename -a "$dir_name"/*/ > dir_list.tmp
done < file_with_list.txt

(正如 jordanm 指出的那样,您不需要引用变量赋值的 RHS。)

【讨论】:

  • 虽然引用扩展名永远不会有什么坏处,但在作业的右侧不会出现分词和通配现象。这里不需要。
  • 我有点忘乎所以。
  • @jordanm 非常感谢,我不知道。让我们去做一些代码清理吧! ;)
【解决方案2】:

假设您的目标是用file_with_list.txt 中列出的每个目录下的目录列表填充dir_list.tmp,这可能会。

#!/bin/bash

inputfile=file_with_list.txt
outputfile=dir_list.tmp
rm -f "$outputfile"        # the -f makes rm fail silently if file does not exist

while read line; do

  # basic syntax checking
  if [[ ! ${line} =~ ^/[a-z][a-z0-9/-]*$ ]]; then
    continue
  fi

  # collect targets using globbing
  for target in "$line"/*; do
    if [[ -d "$target" ]]; then
      printf "%s\n" "$target" >> $outputfile
    fi
  done

done < $inputfile

当您开发任何工具来处理您的dir_list.tmp 文件时,请注意该文件中的特殊字符(包括空格)。

请注意,我使用的是printf 而不是echo,这样第一个字符是连字符的目标不会导致错误。

【讨论】:

    【解决方案3】:

    这可能有效

    while read; do
      find "$REPLY" >> dir_list.tmp
    done < file_with_list.txt
    

    【讨论】:

    • 谢谢,但它不使用基线命令,这是这个问题的主要原因:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    相关资源
    最近更新 更多