![在 bash 中从文本文件中提取文本](https://linux22.com/image/48407/%E5%9C%A8%20bash%20%E4%B8%AD%E4%BB%8E%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E4%B8%AD%E6%8F%90%E5%8F%96%E6%96%87%E6%9C%AC.png)
我有一个很大的文本文件,全是一行。文本中有几个看起来像的部分foo=12345
,我需要将它们全部提取为单独的行,忽略文件的其余部分。
例如:
random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk
我想要出去的是:
12345
2345
7654
5432
我知道如何编写正则表达式来提取foo=([0-9]+)
,但我不确定如何将其应用到文本并在 bash 中取出行。
答案1
$> echo "random junk foo=12345 more junk random junk foo=2345 junk foo=7654 junk random foo=5432 junk" | grep --only-matching --perl-regexp "(?<=foo=)[0-9]+"
12345
2345
7654
5432
我们在这里所做的是在"(?<=foo=)[0-9]+"
.
答案2
我习惯awk
将长行解析为记录。
awk 'BEGIN{FS="=";RS=" "}/^foo=/{print $2}'
这将每个“单词”设置为单独的记录,并在该单词内用“=”分隔字段。然后当左边是“foo”时,只输出‘=’的右边。需要使用正则表达式而不是$1=="foo"
因为如果没有“=”,则第一个字段与整个记录相同。
答案3
您可以单独使用 shell 构造来完成此操作:将数据读入变量,然后在$IFS
(默认为空格)中的字符处拆分该变量并保留所需的块。双引号外的变量替换会经历分词(我们在这里想要的)和文件名生成(又名通配符,我们不想要的),因此首先关闭通配符set +f
。
set +f
for x in $(cat /path/to/file); do
case "$x" in
foo=*) echo "${x#*=}";;
esac
done
set -f
cat
您可以使用内置函数,而不是调用read
。
set +f
read -r line </path/to/file
for x in $line; do …