我有文件名列表 file1,file2,file3
我想在脚本中传递这些文件名并删除特殊字符
我准备了 sed 命令来删除特殊字符
sed -i -e 's/^B/,/g' /home/data/nfiledata/
hdfs dfs -put -f /home/data/nfiledata/* user/sai/table1/nfiledata/
gzip /home/data/nfiledata/*
sed -i -e 's/^B/,/g' /home/data/marginfile/
hdfs dfs -put -f /home/data/marginfile/* user/sai/table2/marginfile/
gzip /home/data/marginfile/*
sed -i -e 's/^B/,/g' /home/data/calldata/
hdfs dfs -put -f /home/data/calldata/* user/sai/table3/calldata/
gzip /home/data/calldata/*
我的问题是,与其多次编写相同的命令,不如在一个命令中编写并使用 Shell 脚本循环每个文件的进程
nfile = (nfiledata,margindata, calldata)
while IFS= read -r nfile
do
sed -i -e 's//,/g' /home/data/$nfile/
hdfs dfs -put -f /home/data/$nfile/* user/sai/table$/$nfile/
gzip /home/data/$nfile/*
done < "home/data/$nfile"
for
循环,而不是while read
循环,在这里是合适的:
nfile=(file1 file2 file3)
for f in "${nfile[@]}"; do
sed -i -e 's/^B/,/g' /home/data/"$f"/ # should this be "$f"/* ?
hdfs dfs -put -f /home/data/"$f"/* user/sai/table1/"$f"/
gzip /home/data/"$f"/*
done
值得注意的组件:
- 作业的
=
周围不得有空格。逗号不是 bash 中数组语法的一部分 - 在这种情况下,不引号、未转义的空格充当分隔符,就像其他地方一样。
扩展 - (如
$f
)必须在双引号内才能安全执行(没有字符串拆分或通配
)。 - 全局扩展,例如
*
,必须是外部引号才能获得。
问题原始版本的答案
同一 sed
命令可以通过一次调用应用于就地编辑多个文件:
sed -i -e 's/old/new/g' /home/data/file1 /home/data/file2 /home/data/file3
另外,如果文件名真的那么简单,则可以使用大括号扩展:
sed -i -e 's/old/new/g' /home/data/file{1..3}
或
sed -i -e 's/old/new/g' /home/data/file[123]
或者,如果没有要排除的其他类似名称的文件,则路径名扩展可能就足够了:
sed -i -e 's/old/new/g' /home/data/file?
真实文件名示例
sed -i -e 's/old/new/g' nfile_dat fileidentifier margindata calldata