【问题标题】:shell script to pass file names and run through [duplicate]用于传递文件名并运行的 shell 脚本 [重复]
【发布时间】: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做什么?

标签: linux bash shell 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/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

【讨论】:

  • /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"/
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-11
  • 1970-01-01
  • 1970-01-01
  • 2017-08-25
  • 1970-01-01
  • 2013-08-06
  • 2023-03-06
相关资源
最近更新 更多