读取文本文件中带有特殊字符的行,特别是 bash shell 中引用的 '<', '>'
reading lines in a text file with special characters specifically as quoted '<', '>' in bash shell
我有一个文本文件,它是两个 grepp 文件的输出差异。文本文件包含如下行 我需要读取文件(循环遍历文本文件中的行)并根据“<”左侧和“>”右侧的文本执行东西.
编辑以添加详细信息:
- < 的左轴或 >
的右轴
- 如果其中任何一个,我需要将内容存储到一个变量中,并获取第一个(ABCDEF)第三个(10)并在其他两个文件之一中搜索(将 grep)它们,如果找到则打印消息并将这些文件名附加到电子邮件 DL 中。所有文件名和目录都存储在单独的变量中。
我该怎么做。
ps:具有文本格式和 bash/shell 命令的基本知识,但仍在学习脚本编写 syntax.Thanks。
ABCDEF,20200101,10 <
PQRSTU,20200106,11 <
LMNOPQ,20200101,12 <
EFGHIJ,20200102,13 <
KLMNOP,20200103,14 <
STUVWX,20200104,15 <
PQRSTU,20200105,16 <
> LMNOPQ,20200101,10
ABCDEF,20200107,17 <
我现在做错了什么?
while IFS= read -r line; do
if $line =~ ([^[:blank:]]+)[[:blank:]]+\<
then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
#echo "f1=$f1 f2=$f2 f3=$f3"
zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3"
elif $line =~ \>[[:blank:]]+([^[:blank:]]+)
then
IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
#echo "g1=$g1 g2=$g2 g3=$g3"
zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3"
fi
你能试试这样的东西吗:
#!/bin/bash
while IFS= read -r line; do
if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< || $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
echo "f1=$f1 f2=$f2 f3=$f3"
# do something here with "$f1", "$f2" and "$f3"
fi
done < file.txt
输出:
f1=ABCDEF f2=20200101 f3=10
f1=PQRSTU f2=20200106 f3=11
f1=LMNOPQ f2=20200101 f3=12
f1=EFGHIJ f2=20200102 f3=13
f1=KLMNOP f2=20200103 f3=14
f1=STUVWX f2=20200104 f3=15
f1=PQRSTU f2=20200105 f3=16
f1=LMNOPQ f2=20200101 f3=10
f1=ABCDEF f2=20200107 f3=17
请将echo "f1=$f1 f2=$f2 f3=$f3"
行修改为您想要的
命令,例如 grep
.
- 正则表达式
([^[:blank:]]+)[[:blank:]]+\<
匹配包含 <
的行
并将 bash 变量 ${BASH_REMATCH[1]}
分配给 LHS。
另一方面,正则表达式 \>[[:blank:]]+([^[:blank:]]+)
做类似的事情
一行包含 >
.
- 语句
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
拆分了bash变量
,
并将 f1、f2 和 f3 分配给字段。
请注意,如果输入文件很大,bash解决方案可能不会
执行时间高效。我使用 bash 只是因为它会很方便
将变量传递给您的 grep
命令。
编辑
关于您问题中更新的脚本,请参考以下修改:
while IFS= read -r line; do
if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< ]]; then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
# echo "f1=$f1 f2=$f2 f3=$f3"
result=$(zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3")
elif [[ $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
# echo "g1=$g1 g2=$g2 g3=$g3"
result=$(zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3")
fi
if [[ -n $result ]]; then
echo "result = $result"
fi
done < file.txt
我有一个文本文件,它是两个 grepp 文件的输出差异。文本文件包含如下行 我需要读取文件(循环遍历文本文件中的行)并根据“<”左侧和“>”右侧的文本执行东西.
编辑以添加详细信息:
- < 的左轴或 > 的右轴
- 如果其中任何一个,我需要将内容存储到一个变量中,并获取第一个(ABCDEF)第三个(10)并在其他两个文件之一中搜索(将 grep)它们,如果找到则打印消息并将这些文件名附加到电子邮件 DL 中。所有文件名和目录都存储在单独的变量中。
我该怎么做。
ps:具有文本格式和 bash/shell 命令的基本知识,但仍在学习脚本编写 syntax.Thanks。
ABCDEF,20200101,10 <
PQRSTU,20200106,11 <
LMNOPQ,20200101,12 <
EFGHIJ,20200102,13 <
KLMNOP,20200103,14 <
STUVWX,20200104,15 <
PQRSTU,20200105,16 <
> LMNOPQ,20200101,10
ABCDEF,20200107,17 <
我现在做错了什么?
while IFS= read -r line; do
if $line =~ ([^[:blank:]]+)[[:blank:]]+\<
then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
#echo "f1=$f1 f2=$f2 f3=$f3"
zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3"
elif $line =~ \>[[:blank:]]+([^[:blank:]]+)
then
IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
#echo "g1=$g1 g2=$g2 g3=$g3"
zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3"
fi
你能试试这样的东西吗:
#!/bin/bash
while IFS= read -r line; do
if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< || $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
echo "f1=$f1 f2=$f2 f3=$f3"
# do something here with "$f1", "$f2" and "$f3"
fi
done < file.txt
输出:
f1=ABCDEF f2=20200101 f3=10
f1=PQRSTU f2=20200106 f3=11
f1=LMNOPQ f2=20200101 f3=12
f1=EFGHIJ f2=20200102 f3=13
f1=KLMNOP f2=20200103 f3=14
f1=STUVWX f2=20200104 f3=15
f1=PQRSTU f2=20200105 f3=16
f1=LMNOPQ f2=20200101 f3=10
f1=ABCDEF f2=20200107 f3=17
请将echo "f1=$f1 f2=$f2 f3=$f3"
行修改为您想要的
命令,例如 grep
.
- 正则表达式
([^[:blank:]]+)[[:blank:]]+\<
匹配包含<
的行 并将 bash 变量${BASH_REMATCH[1]}
分配给 LHS。 另一方面,正则表达式\>[[:blank:]]+([^[:blank:]]+)
做类似的事情 一行包含>
. - 语句
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
拆分了bash变量,
并将 f1、f2 和 f3 分配给字段。
请注意,如果输入文件很大,bash解决方案可能不会
执行时间高效。我使用 bash 只是因为它会很方便
将变量传递给您的 grep
命令。
编辑
关于您问题中更新的脚本,请参考以下修改:
while IFS= read -r line; do
if [[ $line =~ ([^[:blank:]]+)[[:blank:]]+\< ]]; then
IFS=, read -r f1 f2 f3 <<< "${BASH_REMATCH[1]}"
# echo "f1=$f1 f2=$f2 f3=$f3"
result=$(zgrep "$f1" file1 | grep "with seq $f3" || zgrep "$f1" file2 | grep "with seq $f3")
elif [[ $line =~ \>[[:blank:]]+([^[:blank:]]+) ]]; then
IFS=, read -r g1 g2 g3 <<< "${BASH_REMATCH[1]}"
# echo "g1=$g1 g2=$g2 g3=$g3"
result=$(zgrep "$g1" file3 | grep "with seq $g3" || zgrep "$g1" file3 | grep "with seq $g3")
fi
if [[ -n $result ]]; then
echo "result = $result"
fi
done < file.txt