2013-02-17 89 views
1

我写一个程序,将数据的字段创建用户名和密码UNIX的格式化输出变量

下面是如何格式化数据

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 

事情2的事情是错的是

  1. 我想它的用户名后删除的一年。因此,上述 示例将只是MWS。我可以添加到holder =`sed -n “$ {linePosition} p”$ 1 | awk'{print $ 1}'使其仅返回 的前3个字母。 (最好是小写,但不是必需的)

  2. 我想删除电话号码的前6个字母。因此,而不是412/882-0581 如果你正在使用bash的电话号码将改为

+0

需要引用http://tldp.org/LDP/abs/html/string-manipulation.html我会写的页面提供一个答案来解释如何在不久的将来需要时提取字符串。 – 2013-02-17 22:31:19

+0

@ rob-kielty:对不起,并不意味着劫持你的答案!看起来我在添加此评论后几秒钟点击“发布”。 – 2013-02-17 22:33:50

+0

大声笑没关系。有多种方法来清理字符串。 :-我把你的答案和奥拉夫的投票结果投给了你。 – 2013-02-17 22:45:32

回答

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循环,他们运行expr命令传入match,它返回字符串$holder的那部分,该字符串与字符串开始处的正则表达式[A-Z|a-z]*匹配。参考http://tldp.org/LDP/abs/html/string-manipulation.html

现在,如果您的数据文件不是太长,那么这将是确定的。

但是,如果您的脚本必须处理大型数据文件那么我建议您在Olaf的解决方案中看起来漫长而艰难。

为什么?

如果您正在处理大量文件,或者如果您不知道要由脚本处理的文件的大小,最好避免在for循环内执行子shell 。在那里,他利用AWK

奥拉夫的解决方案来进行,你需要有一个重要的优势,所有的工作需要一个单一的过程内发生的处理。而for循环则为您的文件的每一行分叉并执行一个bash 的新实例。昂贵的操作,放置在for循环中时可能会有风险。

对于您的代码,我们可以看到当前的for循环受到一小组行的限制,但如果这种情况经常发生变化或者在for循环中引入了一个bug,从而导致它永远运行,那么脚本可能会对性能产生负面影响的机器。

因此,尽管我的答案可能更容易适应您的代码。如果您需要处理大量数据,Olaf的答案会更好。

+0

谢谢!这适用于除返回4个数字的用户名外。用户名的前3个字母是做什么的。 – onTheInternet 2013-02-17 23:05:19

+0

糟糕!你当然是对的。 1秒。 – 2013-02-17 23:07:26

2

,你都可以做这些事情很容易使用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" 

作为用于转换的字符串在击为小写,参见例如ghostdog74的回答here

3

既然你已经使用awk,可以减少所涉及的命令

awk 'NR >= 11 && NR <= 22 { 
    print "UserName"; 
    print tolower(substr($1, 1, 3)); 
    print "password"; 
    print substr($12, 9); 
    print $7;}' $1