Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 使用awk在shell脚本中按制表符拆分字符串无效_Bash_Shell_Awk - Fatal编程技术网

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