从包含特定列中的字符串的行中提取值

时间:2020-09-03 13:14:50

标签: bash

我有这样的输出:

| Value | Value2 | Name1 | Type | Date | Status |
| Value1 | Value1 | Name1 | Type1 | Date | Success |
| Value2 | Value2 | Name2 | Type1 | Date | Failed |
| Value2 | Value2 | Name3 | Type1 | Date | Pending |

我想获取最后一列中状态为“ Pending”的每一行的变量中的每一列值。

此处匹配的行将是:

| Value2 | Value2 | Name3 | Type1 | Date | Pending |

我想在变量中获取此行的每一列:

myvar1 = Value2 myvar2 = Value2 myvar3 =名称3 myvar4 = Type1 myvar5 =日期

最好的方法是什么?

谢谢

5 个答案:

答案 0 :(得分:1)

首先,您可以选择行。如果只有一个以“待处理”结尾的文件,则可以这样做:

line=$(grep '| Pending |$' file.txt | sed 's/\s*|\s*/|/g' | sed 's/^|//g')

变量line现在仅具有用管道符号分隔的值,没有空格,并且在行首没有管道符号。

然后,如果不使用数组,则可以手动分配变量,例如

myvar1=$(echo $line | awk  -F'|' '{print $1}')
myvar2=$(echo $line | awk  -F'|' '{print $2}')
...

如果有很多行包含关键字“ Pending”,则必须使用数组或动态结构来代替静态变量名。

答案 1 :(得分:1)

我将假设您提到的输出来自名为let str = "10.0"; let f: f32 = match str.parse() { Ok(v) => v, Err(_) => 0.0 // or whatever error handling }; 的命令。例如,如果您将其存储在文件中,则该命令可以为your_command

我认为循环内的开关是一种清晰易懂的解决方案。

cat that_file

具有您所给出的示例的输出如下

your_command | (
    while read line; do
        case $line in
        *'Pending |')
            IFS='|' read -ra myvar <<< "$line"
            echo ${myvar[1]}
            echo ${myvar[2]}
            echo ${myvar[3]}
            echo ${myvar[4]}
            echo ${myvar[5]}
        ;;
        *)
            echo ...IGNORED $line
        ;;
        esac
    done
)

如果由于某种原因不想使用数组,可以将...IGNORED | Value | Value2 | Name1 | Type | Date | Status | ...IGNORED | Value1 | Value1 | Name1 | Type1 | Date | Success | ...IGNORED | Value2 | Value2 | Name2 | Type1 | Date | Failed | Value2 Value2 Name3 Type1 Date 行更改为

IFS='|' read -ra myvar <<< "$line"

答案 2 :(得分:1)

简单地:

while IFS= read -r line ;do
    IFS='|' read -r foo myvar{1..6} foo <<<"$line"
    [ "${myvar6}" ] && [ -z "${myvar6//*Pending*}" ] && echo "$line"
done <inputfile ;

将打印:

| Value2 | Value2 | Name3 | Type1 | Date | Pending |

答案 3 :(得分:0)

首先,您的要求:

IReactComponent

$: while read -r myvar1 myvar2 myvar3 myvar4 myvar5 Pending > do echo "myvar1=[$myvar1] myvar2=[$myvar2] myvar3=[$myvar3] myvar4=[$myvar4] myvar5=[$myvar5]" > done < <( sed -n '/[|]\s*Pending\s*[|]\s*$/{ s,[ |], ,g; s/^ //; s/ $//; p; }' file ) myvar1=[Value2] myvar2=[Value2] myvar3=[Name3] myvar4=[Type1] myvar5=[Date] 仅选择所需的记录(sed)将所有定界符废话转换为单个空格(/[|]\s*Pending\s*[|]\s*$/,如果数据中嵌入了任何空格,则中断),去除开头和结尾的定界符(s,[ |], ,g;),并打印结果(s/^ //; s/ $//;说默认情况下不打印,-n说现在就打印此记录)。

但是我认为您应该认真考虑定界符周围的空间,除非您想将其保留为数据的一部分。我会省略前导定界符或尾随定界符。我也确实考虑将它们放入数组中,尽管我确实了解您可能希望按名称使用这些字段...只是不要调用它们p;,等等。< / p>

答案 4 :(得分:0)

另一个选择是:

awk 'BEGIN { FS=OFS="|" } $(NF-1)~/Pending/ { gsub(/^\s*\|\s*/, "", $0); NF-=2; print $0; }' file.txt | while IFS='|' read myVar1 myVar2 myVar3 myVar4 myVar5
do
    #Do something
done