首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带单元空间的bash阵列

带单元空间的bash阵列
EN

Unix & Linux用户
提问于 2018-12-04 23:25:34
回答 3查看 3.7K关注 0票数 2

我有一个文本日志文件

代码语言:javascript
复制
$ cat aaa
673                  20160405 root "/path_to/gis/20160401/20160301_placement_map_org.dbf" ""
673                  20160405 root "/path_to/gis/20160401/20160310_20160401ent_map_org.dbf" ""
790890               20170201 jle  "/path_to/gis/20160401/Pina (Asc) 20160401 Rapid Report.kmz" ""
5883710              20160406 dho  "/path_to/gis/20160401/20160401_Pina_Asc_Rapid_Report_Minesouth.pdf" ""
673                  20160405 dho  "/path_to/gis/20160401/20160310_20160401 placement map org.dbf" ""

现在,我有了这个脚本输出--文件的完整路径:

代码语言:javascript
复制
#!/bin/bash

function nodatechk() {
    arr=("$@")
    for ((i=3;i<${#arr[@]};i+=5));
    do
      echo "${i}" "${arr[i]}"
    done
}

r=( $(grep gis aaa) ) 

nodatechk "${r[@]}"

输出中断是因为第3行(和第5行)元素中有一个空格,尽管它有双引号。

我怎么才能解决这个问题?(顺便说一句,我知道我可以使用awk或cut打印列,但在这种情况下,我只想使用grep。)谢谢。

EN

回答 3

Unix & Linux用户

发布于 2018-12-05 08:11:27

问题的根源在于:

代码语言:javascript
复制
 r=( $(grep gis aaa) )

您将立即看到如果您尝试:

代码语言:javascript
复制
 printf '<%s>\n' $(grep gis aaa)

在"$IFS“(空格、制表符、换行符默认情况下)中的字符上拆分。

将文件中的值公开给globbing。这将转换一些*?[…] (哪些将取决于pwd上的文件列表和几个shell选项的条件)。

一种(不推荐的)解决方案是将IFS更改为拆分字符禁用拆分的全局操作:

代码语言:javascript
复制
 IFS=但是一个更简单的解决方案是使用shell已经提供的内容:readarray -t r <(grep gis aaa) 这将在新行上拆分(假设路径名中没有换行符)。然后,为了避免再次分割每一行,以获得每一个可能使行暴露在空格分裂和全球化中的部分,让我们移除行的前导部分和尾部部分。如果从每一行中删除从开始到"/ (双引号和斜杠)的所有内容,以及从" (双引号和空格)到末尾的所有内容,我们将得到一个干净的路径名: #!/bin/bash

 function nodatechk() {
    for l do
        l="/${l#*\"/}"                # Remove leading text up to `"/`
        l=${l%\" *}                   # Remove trailing text from `" `
        printf '%s\n' "$l"
    done
 }

 readarray -t r < <(grep gis aaa)

 nodatechk "${r[@]}"\n'; set -f; r=( $(grep gis aaa) )

但是一个更简单的解决方案是使用shell已经提供的内容:

A7

这将在新行上拆分(假设路径名中没有换行符)。

然后,为了避免再次分割每一行,以获得每一个可能使行暴露在空格分裂和全球化中的部分,让我们移除行的前导部分和尾部部分。

如果从每一行中删除从开始到D8 (双引号和斜杠)的所有内容,以及从D9 (双引号和空格)到末尾的所有内容,我们将得到一个干净的路径名:

A10

票数 4
EN

Unix & Linux用户

发布于 2018-12-07 00:02:20

grep-only解决方案是

代码语言:javascript
复制
grep gis aaa | grep -o '^[^"]*"[^"]*"' | grep -o '"[^"]*"第一个grep与您在问题中的内容相同。显然,它选择包含gis (行中任何位置)的行. (第二个grep ),grep -o '^[^"]*"[^"]*"'通过(并包括)行中的第一个引号字符串(即列1到4)匹配所有内容,并且由于-o选项,只能输出这些单词。grep -o '"[^"]*"匹配行上的最后一个单词引号字符串(此时,该字符串是原始行中的第4列),并且只输出该字符串。如果您的文件在每一对列之间有一个选项卡,且值不包含选项卡,那么获取第四列的简单方法是awk -F'\t' '/gis/ { print $4 }' aaa第一个D2与您在问题中的内容相同。显然,它选择包含D3 (行中任何位置)的行. (第二个grep ),A4通过(并包括)行中的第一个引号字符串(即列1到4)匹配所有内容,并且由于<#>D5选项,只能输出这些单词。A6匹配行上的最后一个单词引号字符串(此时,该字符串是原始行中的第4列),并且只输出该字符串。如果您的文件在每一对列之间有一个选项卡,且值不包含选项卡,那么获取第四列的简单方法是A7

匹配行上的最后一个单词引号字符串(此时,该字符串是原始行中的第4列),并且只输出该字符串。

如果您的文件在每一对列之间有一个选项卡,且值不包含选项卡,那么获取第四列的简单方法是

A7

第一个D2与您在问题中的内容相同。显然,它选择包含D3 (行中任何位置)的行. (第二个grep ),

A4

通过(并包括)行中的第一个引号字符串(即列1到4)匹配所有内容,并且由于<#>D5选项,只能输出<#>这些单词。

A6

匹配行上的最后一个单词引号字符串(此时,该字符串是原始行中的第4列),并且只输出该字符串。

如果您的文件在每一对列之间有一个选项卡,且值不包含选项卡,那么获取第四列的简单方法是

A7

票数 0
EN

Unix & Linux用户

发布于 2018-12-06 16:57:20

我读了这个职位,我用'eval‘解决了这个问题。因此改变了这一行:

r=( $(grep gis aaa) )

eval r="( $(grep gis aaa) )"

票数 -1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/486027

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档