在带有选项卡的标准输出上使用 cut

Using cut on stdout with tabs

我有一个文件,其中包含一行带制表符的文本

echo -e "foo\tbar\tfoo2\nx\ty\tz" > file.txt

我想要剪切第一列。如果我这样做它会起作用

$ cut -f 1 file.txt
foo
x

但如果我在 bash 脚本中阅读它

while read line
do
    new_name=`echo -e $line | cut -f 1`
    echo -e "$new_name"
done < file.txt

然后我得到

foo bar foo2
x y z

我做错了什么?

/编辑:我的脚本现在看起来像那样

while IFS=$'\t' read word definition
do
    clean_word=`echo -e $word | external-command'`
    echo -e "$clean_word\t<b>$word</b><br>$definition" >> 
done < 

外部命令从希腊词中删除变音符号。脚本是否可以在不更改的情况下进一步优化 external-command?

发生的事情是您在阅读文件时没有引用 $line。然后,原始的制表符分隔格式丢失了,单词之间显示的不是制表符,而是空格。由于 cut 的默认分隔符是制表符,因此它找不到任何内容并打印整行。

所以引用有效:

while read line
do
    new_name=`echo -e "$line" | cut -f 1`
    #----------------^^^^^^^
    echo -e "$new_name"
done < file.txt

但是请注意,您可以使用 IFS 将制表符设置为字段分隔符并一次读取多个参数:

while IFS=$'\t' read name rest;
do
   echo "$name"
done < file.txt

返回:

foo
x

再次请注意,awk 为此目的甚至更快:

$ awk -F"\t" '{print }' file.txt
foo
x

因此,除非您想在循环文件时调用一些外部命令,否则 awk(或 sed)更好。