我有一个文本日志文件
$ 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" ""现在,我有了这个脚本输出--文件的完整路径:
#!/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。)谢谢。
发布于 2018-12-05 08:11:27
问题的根源在于:
r=( $(grep gis aaa) )您将立即看到如果您尝试:
printf '<%s>\n' $(grep gis aaa)在"$IFS“(空格、制表符、换行符默认情况下)中的字符上拆分。
和将文件中的值公开给globbing。这将转换一些*、?和[…] (哪些将取决于pwd上的文件列表和几个shell选项的条件)。
一种(不推荐的)解决方案是将IFS更改为拆分字符和禁用拆分的全局操作:
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
发布于 2018-12-07 00:02:20
grep-only解决方案是
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
发布于 2018-12-06 16:57:20
https://unix.stackexchange.com/questions/486027
复制相似问题