【问题标题】:How to group comma seperated columns into one single string in a unix for loop如何在unix for循环中将逗号分隔的列分组为一个字符串
【发布时间】:2017-04-03 03:22:58
【问题描述】:

我正在使用一个管道分隔列表(文本文件),它看起来像

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

在第一个循环中,我遍历每个配方名称,并检查每个配方是否存在 list_items。如果是,那么我想将所有列分隔的项目打印为一个字符串,而不是单独的项目。我的意思是所有逗号分隔的项目(在第二个管道符号之后开始)作为一个字符串

像这样:

lettuce, spinach, beans

代替:

lettuce,
spinach,
beans

当我运行代码时出现错误,

line 3: [: too many arguments

不确定,我是否正确使用 AWK。请纠正我。

【问题讨论】:

    标签: unix for-loop awk


    【解决方案1】:

    您的代码有几个问题。

    if [ cat `list_catalog.txt | grep $recipename |  awk -F "|" '{print $3}'` != NULL ]
    

    命令替换引号内的命令以list_catalog.txt 开头,就好像它是命令一样。您可能打算将 cat 放在命令替换引号内。也许这只是您在 Stack Overflow 中输入此问题时的一个错误,因为它给出的错误与您报告的错误不同。

    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 ]
    

    说了这么多,我完全不知道你为什么要这么做。输入文件已经在一行中包含了您的 list_items,这似乎是您的目标。

    【讨论】:

    • 感谢@Bill Karwin。这个双引号工作得很好。我实际上是 unix 新手,我的列表目录包含 100 行这样的行,我正在尝试生成一个 SQL 查询并访问数据库。 select distinct ${list_items} from database.$recipename order by ${list_items} desc。虽然这解决了我的目的,但我正在努力编写更好的代码。顺便说一句,我更正了 if 条件。
    【解决方案2】:

    @try:

    cat script.ksh
    recipe_name="etc"
    awk -vrec_name="$recipe_name" -F"|" '($0 ~ rec_name) && $3{print $3}'  Input_file
    

    只需将字段分隔符设为 |并检查 $3 是否存在,如果是,则打印 $3 表示第三个字段。

    【讨论】:

    • 小心这种情况,它不只是测试是否存在 $3。想一想……
    • 我刚刚编辑了我的代码,因为用户的问题并不清楚,所以现在阅读用户的代码并在上面进行编辑。感谢 Ed 的回复。
    • 我认为你错过了$3{print} 将测试 $3 是否是 presnet 并且不等于数值计算为零的值。如果您只想测试它是否存在,那就是$3!=""{print}。顺便说一句,在 -vrec_name= 之间没有空格会使你的脚本不必要地特定于 gawk。
    猜你喜欢
    • 2021-12-16
    • 2014-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多