关于linux:用于传递文件名并运行的shell脚本

shell script to pass file names and run through

本问题已经有最佳答案,请猛点这里访问。

我有文件名列表file1,file2,file3我想在脚本中传递这些文件名并删除特殊字符

我准备了删除特殊字符的SED命令

1
2
3
sed  -i -e 's/^B/,/g' /home/data/nfiledata/
hdfs dfs -put -f /home/data/nfiledata/*  user/sai/table1/nfiledata/
gzip  /home/data/nfiledata/*
1
2
3
sed  -i -e 's/^B/,/g' /home/data/marginfile/  
hdfs dfs -put -f /home/data/marginfile/*  user/sai/table2/marginfile/
gzip  /home/data/marginfile/*

1
2
3
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脚本循环每个文件的过程吗?

1
2
3
4
5
6
7
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循环:

1
2
3
4
5
6
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命令可应用于通过一次调用就地编辑多个文件:

1
sed  -i -e 's/old/new/g' /home/data/file1 /home/data/file2 /home/data/file3

此外,如果文件名确实如此简单,则可以使用大括号扩展:

1
sed  -i -e 's/old/new/g' /home/data/file{1..3}

或者,

1
sed  -i -e 's/old/new/g' /home/data/file[123]

或者,如果没有要排除的其他同名文件,则路径名扩展可能就足够了:

1
sed  -i -e 's/old/new/g' /home/data/file?

。真实文件名示例

1
sed  -i -e 's/old/new/g' nfile_dat fileidentifier margindata calldata