如何在unix for循环中将逗号分隔的列分组为单个字符串
我正在使用一个管道分隔列表(文本文件),它看起来像如何在unix for循环中将逗号分隔的列分组为单个字符串,unix,for-loop,awk,Unix,For Loop,Awk,我正在使用一个管道分隔列表(文本文件),它看起来像 recipename|category|list_items ------------------------------------------- veg_quesadilla|groupA|lettuce, spinach, beans burrito_bowl|groupA|brown_rice, black_beans, lettuce, pepper french_fries|groupB beverage|groupC|pepsi
recipename|category|list_items
-------------------------------------------
veg_quesadilla|groupA|lettuce, spinach, beans
burrito_bowl|groupA|brown_rice, black_beans, lettuce, pepper
french_fries|groupB
beverage|groupC|pepsi
我有以下声明
for recipename in `head -4 list_catalog.txt | awk -F "|" '{print $1}'`
do
if [ `cat list_catalog.txt | grep $recipename | awk -F "|" '{print $3}'` != NULL ]
then
for list_items in `cat list_catalog.txt | grep $recipename | awk -F "|" '{print $3}'`
do
echo -e ${list_items}
done
fi
done
在第一个循环中,我迭代每个配方名称,并检查每个配方是否存在列表项。如果是,那么我想将所有列中的独立项打印为一个字符串,而不是单独的项。我的意思是所有以逗号分隔的项目(在第二个管道符号之后开始)都作为一个字符串
像这样:
lettuce, spinach, beans
而不是:
lettuce,
spinach,
beans
当我运行代码时,我发现了一个错误
line 3: [: too many arguments
不确定,我是否正确使用AWK。请纠正我 试试看:
cat script.ksh
recipe_name="etc"
awk -vrec_name="$recipe_name" -F"|" '($0 ~ rec_name) && $3{print $3}' Input_file
只需将字段分隔符设置为|并检查$3是否存在(如果是),然后打印$3,这意味着第三个字段。您的代码有几个问题
if [ cat `list_catalog.txt | grep $recipename | awk -F "|" '{print $3}'` != NULL ]
命令替换引号中的命令以list\u catalog.txt
开头,就好像它是命令一样。您可能打算将cat
放在命令替换引号内。在堆栈溢出中键入此问题时,这可能只是一个错误,因为它给出的错误与您报告的错误不同
myscript.sh: line 3: list_catalog.txt: command not found
即使您修复了它,它也会生成一个无效的测试。如果使用调试输出运行sh,则可以发现它:
$ sh -x myscript.sh
...
+ '[' lettuce, spinach, beans '!=' NULL ']'
myscript.sh: line 3: [: too many arguments
...
命令替换返回的单词没有被引用,因此它们显示为单独的单词。的左侧不能有三个单词=代码>操作员
要解决此问题,请将命令替换放在引号内,因此它返回的任何内容都将被视为一个字符串
if [ "`cat list_catalog.txt | grep $recipename | awk -F '|' '{print $3}'`" != NULL ]
尽管如此,我还是不明白你为什么要这么做。输入文件已将您的列表项放在一行上,这似乎是您的目标。小心这种情况,它不仅仅测试3美元是否存在。想想看……我刚刚编辑了我的代码,因为用户的问题不清楚,所以请阅读用户的代码并在上面进行编辑。感谢Ed的回复。我认为您错过了$3{print}
将测试$3是否为presnet且不等于数值计算为零的值。如果你只是想测试它是否存在,那将是$3=“{print}
。顺便说一句,如果在-v
和rec_name=
之间不加空格,会使您的脚本不必要地呆滞特定。谢谢@Bill Karwin。双引号工作得很好。实际上,我是unix新手,我的列表目录包含100行这样的行,我正在尝试生成SQL查询并访问数据库<代码>从数据库中选择不同的${list\u items}。$recipename按${list\u items}描述排序。虽然这解决了我的目的,但我正在努力编写更好的代码。顺便说一句,我纠正了if条件。