#!/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表达式有什么问题,导致只在路径的第一个元素前添加路径?
答案 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 的第一次出现
#
开头,则匹配项将锚定到 $ parameter 还有一点要注意,不要使用ALLCAPS_VARNAMES:覆盖关键的shell变量(例如$ PATH)太容易了。