如何使用awk将目录添加到变量中文件列表的前面?

时间:2019-02-14 22:07:51

标签: bash awk

#!/bin/bash
FILES='a.txt
b.txt
c.txt'
OUT_FILES=$(awk -F ' ' \$0=\"foo/bar/\"\$0 <(echo ${FILES}))

echo ${OUT_FILES}

在上面的脚本中,我希望${OUT_FILES}中的文件列表为foo/bar/a.txt foo/bar/b.txt foo/bar/c.txt,但输出为foo/bar/a.txt b.txt c.txt。稍后,${OUT_FILES}列表将通过xargs提供给另一个命令。 awk表达式有什么问题,导致只在路径的第一个元素前添加路径?

2 个答案:

答案 0 :(得分:4)

缺少引号,也可以通过这种方式进行清理。

$ awk '{print "foo/bar/" $0}' <<< "$FILES"
foo/bar/a.txt
foo/bar/b.txt
foo/bar/c.txt

使用sed

可能更容易
$ sed 's_^_foo/bar/_' <<< "$FILES"
foo/bar/a.txt
foo/bar/b.txt
foo/bar/c.txt

答案 1 :(得分:2)

使用数组是一种更好的存储文件名的方法:

dirname="/tmp/foo"
files=( a.txt b.txt c.txt )
out_files=( "${files[@]/#/$dirname/}" )

让我们看看这些数组现在包含什么:

$ declare -p files out_files dirname
declare -a files='([0]="a.txt" [1]="b.txt" [2]="c.txt")'
declare -a out_files='([0]="/tmp/foo/a.txt" [1]="/tmp/foo/b.txt" [2]="/tmp/foo/c.txt")'

"${files[@]/#/$dirname/}"是一个相当棘手的parameter expansion

  • ${parameter/pattern/string}用给定的 string 替换 pattern 的第一次出现
    • 如果 pattern #开头,则匹配项将锚定到 $ parameter
    • 的值的开头
    • 所以我要在值的开头匹配空字符串,并用$ dirname值和一个斜杠
    • 替换该空字符串。 >
  • 如果 parameter 是数组扩展,则将对数组的每个元素进行模式替换。

还有一点要注意,不要使用ALLCAPS_VARNAMES:覆盖关键的shell变量(例如$ PATH)太容易了。