我有一个以下格式的文本文件:
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-> ->
这意味着,不会发生分裂。我的计划有什么问题?
答案 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
观察文件中的空白区域。在awk
或bash
使用\t
去限制器对此文件进行操作将无效。
答案 2 :(得分:0)
也可以将\t
替换为' - &gt;'与sed
:
sed -e 's/\t/->/g' filename.txt
请注意,这也适用于标题行,因此您可能希望将其排除:
sed -e '2,$s/\t/->/g' filename.txt
但是,您必须确保文本文件在字段之间实际上由一个选项卡分隔。