Bash:读取包含文件中单个或双个单词的变量

时间:2014-10-28 13:56:14

标签: bash shell scripting

我正在尝试使用bash v4.1.x将文件内容读入变量输入文件可能如下所示:

1373232436 785907701 "abc 245" 0 1
1373232436 1048824909 "def pqr" 1 0
1373232486 785907701 "uvw ghn" 0 1
1373232486 1048824909 "1109 xyz" 1 0

如果我使用

cat <filename>|while read col1 col2 col3 col4 col5 col6
do
...
...
done

我应该将col3值设为

"abc 245"
"def pqr"
"uvw ghn"
"1109 xyz"

4 个答案:

答案 0 :(得分:2)

假设只能显示第三个字段,我会使用正则表达式将每一行拆分成列。

while read -r line; do
    [[ $line =~ ^(.*)\ (.*)\ (\".*\")\ (.*)\ (.*)$ ]] || continue
    col1=${BASH_REMATCH[1]}
    col2=${BASH_REMATCH[2]}
    col3=${BASH_REMATCH[3]}
    col4=${BASH_REMATCH[4]}
    col5=${BASH_REMATCH[5]}
done < file.txt

答案 1 :(得分:1)

您也可以使用gawk+FPAT

$ gawk 'BEGIN{FPAT="([^ ]*)|\"([^\"]*)\""} {print "\nLine: " NR; for(i=1;i<=NF;i++){print $i}}'  test.csv
Line: 1
1373232436
785907701
"abc 245"
0
1

Line: 2
1373232436
1048824909
"def pqr"
1
0

Line: 3
1373232486
785907701
"uvw ghn"
0
1

Line: 4
1373232486
1048824909
"1109 xyz"
1
0

注1:FPAT是gawk功能。可能不适用于您的awk版本。
注意2:刚才意识到,顺便说一句,上面提到的链接中的示例处理的要求与您的要求非常相似,尽管我自己编写了正则表达式。 : - )

答案 2 :(得分:0)

我认为,您的输入文件本质上是一个csv文件,字段分隔符=空格 然后,您可以使用csvtool

csvtool -t " " cols 1-6 test.csv | while IFS=, read col1 col2 col3 col4 col5 col6; do
    ...
    ...
done

运行csvtool --help了解更多详情。

注意:col3数据周围不会有双引号。所以你会得到abc 245&amp;价值中没有"abc 245"

答案 3 :(得分:0)

您实际上可以使用:

grep -Eo '"[^"]*"|\w+' file

从输入文件中单独读取每个引用列。

您可以使用以下脚本:

#!/bin/bash

numcols=$(awk -F '"[^"]*"|[^[:blank:]]+' '{print NF-1; exit}' file)

n=1
while read -r w; do
    echo "$w"
    (( (n++ % numcols) )) || echo "<-- End of line $(( (n / numcols) )) -->"
done < <(grep -Eo '"[^"]*"|\w+' file)

对于您的输入文件,它提供:

1373232436
785907701
"abc 245"
0
1
<-- End of line 1 -->
1373232436
1048824909
"def pqr"
1
0
<-- End of line 2 -->
1373232486
785907701
"uvw ghn"
0
1
<-- End of line 3 -->
1373232486
1048824909
"1109 xyz"
1
0
<-- End of line 4 -->

您可以单独处理它们,而不是执行echo "$w"