用于传递文件名并运行的 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 很可能file1
、file2,
等只是替身,真正的文件名更复杂。但是,如果没有,我会将您的建议添加到答案中。
感谢约翰的回答。如果我的文件名不同,例如 (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,当然;将您想要的实际目录名称放入数组内容中。 (您的代码是用file1
、file2
和file3
编写的,它们是目录名,而不是文件名;如果它们实际上是文件名,那么由于尾随/
s,最初建议的命令也不正确)。
@Sai, ...所以,如果它们实际上是文件,请将其设置为 /home/data/"$f"
,当前写入 /home/data/"$f"/*
或 /home/data/"$f"/
。以上是关于用于传递文件名并运行的 shell 脚本 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
用于确保在任何给定时间仅运行一个 shell 脚本的 shell 片段 [重复]
使用shell脚本登录远程linux服务器并运行一些基本命令[重复]