存储在变量中的Glob字符串在命令

时间:2017-10-27 08:26:42

标签: bash

我试图处理一组具有各种扩展名的文件,但我没有经历过bash的内部工作......这就是我所做的事情。试图完成(剥离):

DOCUMENT_SOURCE_FILE_PATTERN="*.{yaml,md}";
pandoc -s -f markdown -o combined.html $DOCUMENT_SOURCE_FILE_PATTERN;

结果

pandoc: *.{yaml,md}: openFile: does not exist (No such file or directory)

而我直接这样做

pandoc -s -f markdown -o combined.html *.{yaml,md};

效果很好。

$DOCUMENT_SOURCE_FILE_PATTERN的值实际上是由命令行参数生成的,而不是硬编码的,否则上面示例中的直接方法已经足够好了。

根据要求,这是一个完全自包含的示例

将以下代码放入空目录

中的test.sh脚本中
#!/bin/bash

# setup
touch 0001.md
touch 0002.md
touch metadata.yaml

# actual functionality under test
DOCUMENT_SOURCE_FILE_PATTERN="yaml,md";

shopt -s nullglob;
DOCUMENT_SOURCE_FILES=( *.{$DOCUMENT_SOURCE_FILE_PATTERN} );

echo "required logic below:";
echo "${DOCUMENT_SOURCE_FILES[@]}";

echo;
echo "working solution with hardcoding:";
DOCUMENT_SOURCE_FILES=( *.{yaml,md} );
echo "${DOCUMENT_SOURCE_FILES[@]}";

# tear down
rm *.{yaml,md};

2 个答案:

答案 0 :(得分:2)

不要尝试在变量中添加glob字符串。使用数组并执行引用的数组扩展。 nullglob是为了确保 literal glob字符串不会传递给数组,而只传递扩展列表(如果可用)

shopt -s nullglob
document_source_file_pattern=( *.{yaml,md} )

并将数组作为

传递
pandoc -s -f markdown -o combined.html "${document_source_file_pattern[@]}"

作为下面你可以做的另一个安全方法,运行你的pandoc命令只有数组非零。

(( "${#document_source_file_pattern[@]}" )) &&
    pandoc -s -f markdown -o combined.html "${document_source_file_pattern[@]}"

答案 1 :(得分:1)

在这一行中,您尝试进行双重展开(首先$DOCUMENT_SOURCE_FILE_PATTERN,然后是结果模式):

DOCUMENT_SOURCE_FILES=( *.{$DOCUMENT_SOURCE_FILE_PATTERN} );

你不能直接这样做。

如果您相信$DOCUMENT_SOURCE_FILE_PATTERN不会包含恶意输入,那么您可以使用eval实现您想要的目标:

eval DOCUMENT_SOURCE_FILES=( *.{$DOCUMENT_SOURCE_FILE_PATTERN} )

但相反,您可以(应该)尝试以不同的方式执行此操作,例如将您想要的文件添加到数组中,而不是尝试在代码中动态创建大括号扩展:

# prevent literal globs being added to the array when no files match
shopt -s nullglob 

source_files=()
if <whatever condition to add markdown files>; then
    source_files+=( *.md )
fi

if <whatever condition to add yaml files>; then
    source_files+=( *.yaml )
fi