用于传递文件名并运行的 shell 脚本 [重复]

Posted

技术标签:

【中文标题】用于传递文件名并运行的 shell 脚本 [重复]【英文标题】:shell script to pass file names and run through [duplicate] 【发布时间】:2016-09-24 23:50:56 【问题描述】:

我有文件名列表 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"

【问题讨论】:

你希望sed 's//,/g' 做什么? files=( file1 file2 file3 ) 是正确的数组赋值语法。 =s 周围不能有空格,不能有逗号。 我强烈建议您通过shellcheck.net 运行您的代码,并在此处提问之前修复它找到的所有内容。 sed 通常对文件而不是目录进行操作。在代码sed -i -e 's/^B/,/g' /home/data/file1/ 中,你期望sed做什么? 【参考方案1】:

原始版本问题的答案

同样的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/file1..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

【讨论】:

/home/data/file[123]/home/data/file? 怎么样? @MaxU 是的。我最初没有显示,因为 OP 很可能file1file2, 等只是替身,真正的文件名更复杂。但是,如果没有,我会将您的建议添加到答案中。 感谢约翰的回答。如果我的文件名不同,例如 (nfile_dat, fileidentifier,margindata,calldata) 怎么办?另外我如何循环数据 @Sai 我刚刚在答案中添加了一个使用这些文件名的示例。【参考方案2】:

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 等扩展必须在双引号内才能安全执行(不进行字符串拆分或通配)。 全局扩展,例如*,必须在引号之外才能被接受。

【讨论】:

谢谢查尔斯。即使我的文件名不同,我也可以使用这个脚本吗?正确的?我的文件名就像 (nfile_dat, fileidentifier,margindata,calldata) 。每个文件代表我的 hadoop 中的一个表。 @Sai,当然;将您想要的实际目录名称放入数组内容中。 (您的代码是用file1file2file3 编写的,它们是目录名,而不是文件名;如果它们实际上是文件名,那么由于尾随/s,最初建议的命令也不正确)。 @Sai, ...所以,如果它们实际上是文件,请将其设置为 /home/data/"$f",当前写入 /home/data/"$f"/*/home/data/"$f"/

以上是关于用于传递文件名并运行的 shell 脚本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章

用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]

参数传递:shell脚本调用一个带参数的python函数

用于在文件中添加数据的 shell 脚本 [重复]

使用shell脚本登录远程linux服务器并运行一些基本命令[重复]

如何将shell脚本中定义的变量用于Scala文件? [重复]

Bash脚本不处理传递的输入参数[重复]