使用awk在shell脚本中按选项卡拆分字符串不起作用

时间:2017-01-24 06:40:56

标签: bash shell awk

我有一个以下格式的文本文件:

Name           Place     Mobile
Jon Sam        India     1234567890
Barack Obama   USA       0987654321

每个字段由制表符空格分隔。我想通过shell脚本提取每个字段。我使用以下代码:

while IFS= read -r var; do 
    echo $var | awk -F"\t" '{print $1,"->"$2,"->"$3}'
done < myfile

我期待以下风格的输出:

Jon Sam->India->1234567890

但它的打印方式如下:

Jon Sam India 1234567890-> ->

这意味着,不会发生分裂。我的计划有什么问题?

3 个答案:

答案 0 :(得分:5)

当你在bash中拥有完美的格式化工具时,仅使用awk进行格式化似乎很浪费。

-w

或者,如果你真的想在事后分开这行:

while IFS=$'\t' read -r var1 var2 var3; do
    printf "%s->%s->%s\n" "$var1" "$var2" "$var3"
done < myfile

当然,awk毫不费力地做了这样的事情:

while IFS= read -r line; do
    IFS=$'\t' read -r -a arr <<<"$line"
    printf "%s->%s->%s\n" "${arr[@]}"
done < myfile

甚至

awk -F"\t" '{ printf "%s->%s->%s\n",$1,$2,$3 } ' myfile

答案 1 :(得分:3)

假设您的输入行被\t分开,awk OFS输出字段分隔符设置为->并重建这些行应该为您完成工作。

awk 'BEGIN{FS="\t";OFS="->"}{$1=$1}1' file
Name->Place->Mobile
Jon Sam->India->1234567890
Barack Obama->USA->0987654321

请记住,上述命令适用于此\t分隔的输入文件

$ cat file
Name    Place   Mobile
Jon Sam India   1234567890
Barack Obama    USA     0987654321

观察下面字符串之间的\t

hexdump -c file
0000000   N   a   m   e  \t   P   l   a   c   e  \t   M   o   b   i   l
0000010   e  \n   J   o   n       S   a   m  \t   I   n   d   i   a  \t
0000020   1   2   3   4   5   6   7   8   9   0  \n   B   a   r   a   c
0000030   k       O   b   a   m   a  \t   U   S   A  \t   0   9   8   7
0000040   6   5   4   3   2   1  \n
0000047

现在转到原始输入文件

hexdump -c original-file
0000000   N   a   m   e                                               P
0000010   l   a   c   e                       M   o   b   i   l   e  \n
0000020   J   o   n       S   a   m                                   I
0000030   n   d   i   a                       1   2   3   4   5   6   7
0000040   8   9   0  \n   B   a   r   a   c   k       O   b   a   m   a
0000050               U   S   A                               0   9   8
0000060   7   6   5   4   3   2   1  \n
0000068

观察文件中的空白区域。在awkbash使用\t去限制器对此文件进行操作将无效。

答案 2 :(得分:0)

也可以将\t替换为' - &gt;'与sed

sed -e 's/\t/->/g' filename.txt

请注意,这也适用于标题行,因此您可能希望将其排除:

sed -e '2,$s/\t/->/g' filename.txt

但是,您必须确保文本文件在字段之间实际上由一个选项卡分隔。