Bash 使用awk在shell脚本中按制表符拆分字符串无效
我有一个以下格式的文本文件:Bash 使用awk在shell脚本中按制表符拆分字符串无效,bash,shell,awk,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}'
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-> ->
也就是说,没有分裂发生。我的程序出了什么问题?假设您的输入行是分开的,
\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
de limiter操作此文件将不起作用。如果bash中有非常好的格式化工具,仅将awk用于格式化似乎是浪费
while IFS=$'\t' read -r var1 var2 var3; do
printf "%s->%s->%s\n" "$var1" "$var2" "$var3"
done < myfile
甚至
awk -F"\t" -v OFS="->" '{ $1=$1 } 1' myfile
也可以将
\t
替换为“->”为sed
:
sed -e 's/\t/->/g' filename.txt
请注意,这也适用于标题行,因此您可能希望排除它:
sed -e '2,$s/\t/->/g' filename.txt
但是,您必须确保文本文件实际上由字段之间的一个选项卡分隔。首先,这似乎很愚蠢——当您可以直接使用
awk
读取myfile
时,为什么要在循环中读取输入?其次,在bash中,始终引用变量。尝试使用echo“$var”| awk…
,看看这是否有所不同。然后完全停止使用while循环。。。为什么你的预期输出<代码>乔恩山姆- > KoCH-> 1234567890 ,在中间有<代码> Kochin <代码>,而输入有不同的代码?@ GHOTI谢谢。我使用while循环是因为在每一行上我都要执行更多的操作。@Inian这是一个错误。问题已修改。谢谢。@INIA输入文件字段由\t
分隔。为了便于阅读,我在这里用多个空格隔开。对于awk版本来说,它们比Bash版本更简单、更直接。
awk -F"\t" -v OFS="->" '{ $1=$1 } 1' myfile
sed -e 's/\t/->/g' filename.txt
sed -e '2,$s/\t/->/g' filename.txt