我正在尝试构建一个脚本,其中一部分内容使用了“sed'将文件名标记到该文件中每行的末尾,然后将输出转储到主列表。 脚本给我带来麻烦的部分在这里:
DIR=/var/www/flatuser
FILES=$DIR/*
for f in $FILES
do
echo "processing $f file...."
sed -i "s/$/:$f/" $f
cat $f >> $DIR/master.txt
done
问题在于' sed'声明在for循环之外工作正常,但是当我把它放在脚本中时,我相信它有解释美元符号的问题。我已经尝试了几乎每一个"和'我可以想到让它来解释变量,它不断地放置" $ f"在每一行的末尾,或者它完全失败。
感谢您的任何意见!
答案 0 :(得分:5)
你只需要逃脱美元符号:
sed -i "s/\$/:$f/" "$f"
以便shell将字面意思传递给sed
。
扩展Charles Duffy关于引用变量的观点:
DIR=/var/www/flatuser
for f in "$DIR"/*
do
echo "processing $f file...."
sed -i "s/\$/:${f##*/}/" "$f"
cat "$f" >> "$DIR/master.txt"
done
如果任何文件名包含空格,如果将文件名列表分配给$FILES
,则对它做任何事都为时已晚;您不能再区分属于文件名的空格和分隔文件名的空格。您可以使用数组,但将glob直接放入for循环更简单。以下是使用数组的方法:
DIR=/var/www/flatuser
FILES=( "$DIR"/* )
for f in "${FILES[@]}"
do
echo "processing $f file...."
sed -i "s/\$/:${f##*/}/" "$f"
cat "$f" >> "$DIR/master.txt"
done
对于不使用sed
的{{1}}版本,这里有一种显式处理模拟就地编辑所需的临时文件的方法:
-i
答案 1 :(得分:3)
就个人而言,我会这样做:
dir=/var/www/flatuser
for f in "$dir"/*; do
[[ $f = */master.txt ]] && continue
while read -r; do printf '%s:%s\n' "$REPLY" "${f##*/}"; done <"$f"
done >/var/www/flatuser/master.txt
它不会像sed -i
那样就地修改您的文件,因此可以安全地运行多次(sed -i
版本会将名称添加到您的文件中它运行的时间,所以你最终每行都有多个文件名副本。)
此外,POSIX未指定sed -i
,因此并非所有操作系统都会拥有它。
答案 2 :(得分:0)
问题不在于美元符号。这是变量$ f包含一个“/”字符,而sed使用它来分隔表达式。尝试使用“@”作为分隔符。
DIR=/var/www/flatuser
FILES=$DIR/*
for f in $FILES
do
echo "processing $f file...."
sed -i s@"$"@:"$f"@ $f
cat $f >> $DIR/master.txt
done
答案 3 :(得分:0)
DIR=/var/www/flatuser
FILES=( "$DIR"/* )
for f in "${FILES[@]}"
do
echo "processing $f file...."
b=`basename $f`
sed -i "s/\$/:${b##*/}/" "$b"
cat "$f" >> "$DIR/master.txt"
done
未经测试......