我正在编写一个程序,它将采用数据字段来创建用户名和密码
以下是数据的格式化方式
MWS1990 XXX-XX-XXXX STASNY, MATTHEW W SO-II BISS CPSC BS INFO TECH 412/882-0581
这是程序
for linePosition in {11..22}
do
holder=`sed -n "${linePosition}p" $1|awk '{print $1}'`
holder2=`sed -n "${linePosition}p" $1|awk '{print $12}'`
holder3=`sed -n "${linePosition}p" $1|awk '{print $7}'`
echo "UserName"
echo "$holder"
echo "password"
echo "$holder2"
echo "$holder3"
done
它返回这样的输出
UserName
MWS1990
password
412/882-0581
BISS
有两件事是错误的
我希望删除用户名后的年份。所以上面 例如,仅仅是MWS。我可以添加什么 holder =`sed -n “$ {linePosition} p”$ 1 | awk'{print $ 1}'让它返回 前3个字母。 (最好是小写但不是必要的)
我想删除电话号码的前6个字母。因此,而不是 412 / 882-0581 电话号码为 0581
答案 0 :(得分:3)
由于您已经使用awk
,因此可以减少所涉及的命令
awk 'NR >= 11 && NR <= 22 {
print "UserName";
print tolower(substr($1, 1, 3));
print "password";
print substr($12, 9);
print $7;}' $1
答案 1 :(得分:2)
如果您正在使用Bash,则可以使用Bash substring extraction轻松完成这两项工作(另请参阅here)。
换句话说,比如:
echo ${holder2:0:3} # "MWS"
echo ${holder3:8:12} # "0581"
# Or, to begin indexing from the right end:
echo ${holder3:(-4)} # "0581"
至于在Bash中将字符串转换为小写,请参阅例如ghostdog74的回答here。
答案 2 :(得分:2)
所以这是修改后的答案
for linePosition in {11..22}
do
holder=`sed -n "${linePosition}p" $1|awk '{print $1}'`
holder2=`sed -n "${linePosition}p" $1|awk '{print $12}'`
holder3=`sed -n "${linePosition}p" $1|awk '{print $7}'`
echo "UserName"
echo `expr match "$holder" '\([A-Z|a-z]*\)'`
echo "password"
echo ${holder2: -4}
echo "$holder3"
done
现在我坚持使用bash字符串替换,如我在评论中发布的链接所述。
但是我想指出以下有关此解决方案的警告
以下是对以下bash脚本行的快速描述......
`expr match "$holder" '\([A-Z|a-z]*\)'`
反引号在for循环中执行子shell ,并运行传递expr
的{{1}}命令,返回匹配的match
字符串部分字符串开头的正则表达式$holder
。参考http://tldp.org/LDP/abs/html/string-manipulation.html
现在,如果您的数据文件不是太长,那么这将是正常的。
但是,如果您的脚本必须处理大型数据文件,那么我建议您查看Olaf的解决方案。
为什么?
如果您正在处理大量文件,或者如果您不知道脚本要处理的文件大小,则最好避免在for循环中执行子shell 。
奥拉夫的解决方案,他利用 awk 来执行您需要的处理具有一个重要优势,因为所有工作都在一个进程中进行 。而for循环为文件的每一行分叉和执行bash 的新实例。一个昂贵的操作,当放在for循环中时可能有风险。
对于你的代码,我们可以看到当前for循环受一小组行的约束,但如果这个行被更改或者一个bug被引入for循环,那么它会永远运行,那么脚本会对性能产生负面影响。你的机器。
因此,虽然我的答案可能更容易适应您的代码。如果你必须处理大量数据,奥拉夫的答案会更好。