Basename将单引号放在变量周围

时间:2012-07-29 01:08:10

标签: macos bash quotes

我正在编写一个简单的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/*/'

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

现在,我知道必须有一千种方法来解决基本名称问题,但是后来我什么都没学到,对吧? ;)

如何摆脱单引号? 如果我的目录名中有空格?

2 个答案:

答案 0 :(得分:1)

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

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

(正如约旦所指出的,你不需要引用变量赋值的RHS。)

答案 1 :(得分:1)

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

#!/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,因此第一个字符为连字符的目标不会导致错误。