shell - 为什么当环境将 Dev 更改为 Prod 时,此 Unzip shell 脚本的行为会有所不同?
问题描述
output_path=s3://output
unziped_dir=s3://2019-01-03
files=`hadoop fs -ls $output_path/ | awk '{print $NF}' | grep .gz$ | tr '\n' ' '`;
for f in $files
do
echo "available files are: $f"
filename=$(hadoop fs -ls $f | awk -F '/' '{print $NF}' | head -1)
hdfs dfs -cat $f | gzip -d | hdfs dfs -put - $unziped_dir"/"${filename%.*}
echo "unziped file names: ${filename%.*}"
done
输出:
开发:
available files are: s3://2019-01-03/File_2019-01-03.CSV.gz
unziped file names: File_2019-01-03.CSV
available files are: s3://2019-01-03/Data_2019-01-03.CSV.gz
unziped file names: Data_2019-01-03.CSV
available files are: s3://2019-01-03/Output_2019-01-03.CSV.gz
unziped file names: Output_2019-01-03.CSV
产品:
available files are: s3://2019-01-03/File_2019-01-03.CSV.gz s3://2019-01-03/Data_2019-01-03.CSV.gz s3://2019-01-03/Output_2019-01-03.CSV.gz
unziped file names:
我正在尝试查看目录并识别 .gz 文件并迭代它们以解压缩所有 .gz 文件并存储到不同的目录中。但是当我在EMR 开发集群中运行这个脚本时,它工作正常。但在产品集群中它不是。请找到上面脚本的行为。
解决方案
单词拆分似乎有问题for f in $files
。通常,shell 应该$files
像在 Dev 上那样在空格处拆分值。On Devf
设置为$files
循环的每个循环中的三个单词之一for
,on Prodf
获得$files
包含空格的完整值。
你在IFS
某处设置变量吗?
如果问题不在脚本的其他部分,您应该能够使用简化的脚本重现问题:
files="foo bar baz"
for f in $files
do
echo "available files are: $f"
done
如果这个最小脚本没有显示出差异,则问题出在脚本的其他部分。
要查看 Dev 和 Prod 的值是否不同,您可以将其添加到最小脚本或循环IFS
之前的原始脚本:for
# To see if IFS is different. With the default value (space, tab, newline) the output should be
# 0000000 I F S = # \t \n # \n
# 0000012
echo "IFS=#${IFS}#" | od -c
如果您看到值的差异,则IFS
必须找出IFS
修改的位置。
顺便说一句:通常你可以| tr '\n' ' '
在 grep 命令之后省略。处理时,shell 应接受\n
作为分词字符for f in $files
。如果不是,这可能与您的问题的根源有关。
编辑:有一个更好的解决方案来逐行处理数据,请参阅
https://mywiki.wooledge.org/DontReadLinesWithFor和
https://mywiki.wooledge.org/BashFAQ/001
您应该使用while read
... 而不是for
...
修改后的脚本(未经测试)
output_path=s3://output
unziped_dir=s3://2019-01-03
hadoop fs -ls "$output_path"/ | awk '{print $NF}' | grep .gz$ | while IFS= read -r f
do
echo "available files are: $f"
filename=$(hadoop fs -ls "$f" | awk -F '/' '{print $NF}' | head -1)
hdfs dfs -cat "$f" | gzip -d | hdfs dfs -put - "${unziped_dir}/${filename%.*}"
echo "unziped file names: ${filename%.*}"
done
推荐阅读
- c - 如何使用指针访问 C 中的多维字符串数组
- javascript - 如何从 Promise 结果创建数组?
- python - Python 动态模块导入 importlib.import_module
- apache-spark - 如何在 Databricks Notebook 中调用集群 API 并启动集群?
- orocrm - 更新确认电子邮件迁移
- r - /usr/local/lib64/R/lib/libR.so:无法打开共享对象文件:没有这样的文件或目录
- javascript - 我应该如何在 .push 中使用 await?
- python-3.x - 用于spidev的构建轮子失败
- javascript - 如何获得输入以接受正确的值并改变颜色?
- python - 如何使用按钮阅读文本