假设有一个简单的脚本.
for file in `hadoop classpath | tr ':' ' ' | sort | uniq`; do echo $file; done
Run Code Online (Sandbox Code Playgroud)
和原始输出hadoop classpath 看起来像这样(文件夹列表在哪里寻找罐子):
zsh %> hadoop classpath
/usr/local/hadoop/etc/hadoop:/usr/local/hadoop/share/hadoop/common/lib/*:/usr/local/hadoop/share/hadoop/common/*:/usr/local/hadoop/share/hadoop/hdfs:/usr/local/hadoop/share/hadoop/hdfs/lib/*:/usr/local/hadoop/share/hadoop/hdfs/*:/usr/local/hadoop/share/hadoop/yarn/lib/*:/usr/local/hadoop/share/hadoop/yarn/*:/usr/local/hadoop/share/hadoop/mapreduce/lib/*:/usr/local/hadoop/share/hadoop/mapreduce/*:/usr/local/hadoop/contrib/capacity-scheduler/*.jar
Run Code Online (Sandbox Code Playgroud)
如果我在Bourne shell中运行上面的脚本,结果将是这样的(它将给出指定类路径中包含的所有jar的唯一列表):
bash-4.1$ for file in `hadoop classpath | tr ':' ' ' | sort | uniq`; do echo $file; done
/usr/local/hadoop/etc/hadoop
/usr/local/hadoop/share/hadoop/common/lib/activation-1.1.jar
/usr/local/hadoop/share/hadoop/common/lib/asm-3.2.jar
/usr/local/hadoop/share/hadoop/common/lib/avro-1.7.4.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-beanutils-1.7.0.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-beanutils-core-1.8.0.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-cli-1.2.jar
/usr/local/hadoop/share/hadoop/common/lib/commons-codec-1.4.jar
...
Run Code Online (Sandbox Code Playgroud)
然而,在zsh中,我仍然得到:
zsh %> for file in `hadoop classpath | tr ':' ' ' | sort | uniq`; do echo $file; done
/usr/local/hadoop/etc/hadoop
/usr/local/hadoop/share/hadoop/common/lib/*
/usr/local/hadoop/share/hadoop/common/*
/usr/local/hadoop/share/hadoop/hdfs
/usr/local/hadoop/share/hadoop/hdfs/lib/*
/usr/local/hadoop/share/hadoop/hdfs/*
/usr/local/hadoop/share/hadoop/yarn/lib/*
/usr/local/hadoop/share/hadoop/yarn/*
/usr/local/hadoop/share/hadoop/mapreduce/lib/*
/usr/local/hadoop/share/hadoop/mapreduce/*
/usr/local/hadoop/contrib/capacity-scheduler/*.jar
Run Code Online (Sandbox Code Playgroud)
(即只是类路径中的文件夹).
为了好奇,将目录列表转换为zsh中的文件排序列表的方法是什么?
有问题的系统是Red Hat Enterprise Linux Server 6.5版.
与Bourne shell不同,zsh在扩展参数后不执行文件名生成.即$x它正是它所说的,变量的值x作为一个参数传递而没有拆分或文件名扩展.要强制进行空格分割,请使用${=x}或调用setopt sh_word_split.要强制扩展文件名,请使用${~x}或调用setopt glob_subst.为防止zsh在目录不包含文件时抱怨,请使用为模式持续时间(N)设置NULL_GLOB选项的修饰符.
将所有这些结果组合在一起:
classpath=$(hadoop classpath | tr ':' ' ' | sort | uniq)
for file in ${=~classpath}(N); do
echo $file
done
Run Code Online (Sandbox Code Playgroud)
请注意,如果您使用的是GNU排序(Linux上的默认设置),sort | uniq则可以缩短sort -u.