我有一个zsh shell脚本问题:-( 有一个包含4列列表的文件:
NAME SURNAME OLD TOWN
DOE John 30 London
CALAS Maria 50 Athens
...
我想对每一行的一些“元素”进行处理。例如,我不知道是否可能,但它应该是:
for user,livesIn in `cat MyFile | awk '{print $2 $4}'`
echo "My friend $user lives in $livesIn"
done
当然这个代码是错的,我没有找到如何正确编写它。 有人知道这是否可能?
提前感谢您的帮助。
答案 0 :(得分:1)
awk
一次处理一行,因此不需要for循环。同样不需要cat
作为awk
将文件名作为参数。试试这个:
awk '{print "My friend "$2" lives in "$4}' MyFile
答案 1 :(得分:1)
如果您已使用awk
,为什么不使用awk
处理所有内容?
例如:
$ awk '{print "My friend", $2, "lives in", $4}' MyFile
获得您正在寻找的输出。除非问题中没有其他内容。
答案 2 :(得分:1)
如果要循环浏览awk的输出,可以尝试
awk '{print $2 $4}' MyFile | while read -r user livesIn; do
echo "${user} was last seen in ${livesIn}."
done
在这种情况下,不需要awk
:
while read -r field1 user field3 livesIn; do
echo "${user} was last seen in ${livesIn}."
done < MyFile
当某些字段有空格时,上述结构将失败,例如New York
仔细查看MyFile的规格,如何分隔字段。固定宽度? TAB字符?有了TAB,你很幸运:
while IFS=$'\t' read -r field1 user field3 livesIn; do
echo "${user} was last seen in ${livesIn}."
done < MyFile
答案 3 :(得分:0)
在AWK中执行迭代和处理通常更简单,更有效,而不是尝试通过在shell中迭代并在AWK中处理来划分任务。 AWK非常适合迭代输入,它也有自己的循环结构(例如for
)。如果可能的话,在AWK中进行所有处理。
也就是说,您的问题似乎也需要访问shell中的输入字段,因此在您的情况下可能无法在AWK中进行完整处理。 (值得注意的是,AWK也可以执行shell命令,但这可能只是另一个复杂程度。)
其他答案使用AWK迭代文件并打印第2列和第4列的内容,如
$ awk '{print "My friend", $2, "lives in", $4}' MyFile
如果您可以像这样使用AWK迭代并处理,那就没问题了。作为此类解决方案的补充,您可能希望跳过第一行(似乎有列标题而不是实际数据)
$ awk 'NR>1{print "My friend", $2, "lives in", $4}' MyFile
您的评论
事实上,我的处理比印刷品复杂一点。我需要在&#34; for&#34;中做一些测试和作业。循环。
建议您真正想要的是访问shell中的字段。你可以通过使用AWK来挑选字段(如前所述),但将值汇总到shell中:
awk 'NR>1{print $2,$4}' MyFile | while read user livesIn; do
echo "My friend $user lives in $livesIn"
done
这会在shell中为您提供$user
和$livesIn
,因此您可以使用它进行更复杂的shell处理。例如:
awk 'NR>1{print $2,$4}' MyFile | while read user livesIn; do
if [[ "$user" == "John" ]]; then
echo "$user is not my friend, but lives in $livesIn"
else
echo "My friend $user lives in $livesIn"
echo "$user" >> friends.txt
fi
done
请注意输入文件的格式,因为AWK在空白处分割。