Bash Shell读取文本赋值时的复杂分隔符问题求解
解决Bash read循环的复杂分隔符提取问题
问题背景
使用Bash的read循环读取文本文件时,需要提取域名、关键词、标题三个变量,但变量值本身包含空格和-,默认以空格作为分隔符会导致内容被错误拆分,无法正确提取目标变量。
输入文件(file.txt)内容
domain_wisgene.com keyword谷歌搜索 - This,is,keyword,google,search,awesome title谷歌搜索 - Google,Search,is,Awesome
当前使用的错误代码
while IFS= read -r -d '' now_list_url now_list_keyword now_list_title; do # Do something with the variables here echo "domain_name:${now_list_url}" echo "Key words:${now_list_keyword}" echo "title:${now_list_title}" done <file.txt
当前错误输出
#domain domain_name:domain_wisgene.com #keywords Key words:keyword谷歌搜索 #title title:- This,is,keyword,google,search,awesome title谷歌搜索 - Google,Search,is,Awesome
期望正确输出
domain_name:domain_wisgene.com Key words:keyword谷歌搜索 - This,is,keyword,google,search,awesome title:title谷歌搜索 - Google,Search,is,Awesome
解决方案
根据文本格式的固定特征(域名是第一个字段,关键词以keyword开头,标题以title开头),提供两种可靠的提取方案:
方案一:纯Bash正则匹配(推荐)
利用Bash的正则表达式匹配能力,精准拆分三个变量,无需依赖外部工具:
while IFS= read -r line; do # 正则匹配拆分域名、关键词、标题 if [[ $line =~ ^([^[:space:]]+)\ +(keyword.*?)\ +(title.*)$ ]]; then now_list_url="${BASH_REMATCH[1]}" now_list_keyword="${BASH_REMATCH[2]}" now_list_title="${BASH_REMATCH[3]}" # 输出提取结果 echo "domain_name:${now_list_url}" echo "Key words:${now_list_keyword}" echo "title:${now_list_title}" fi done < file.txt
正则说明:
^([^[:space:]]+):匹配行首所有非空格字符,即域名\ +:匹配一个或多个空格作为分隔符(keyword.*?):非贪婪匹配从keyword开头到下一个title前的所有内容(确保不包含标题部分)(title.*)$:匹配从title开头到行尾的所有内容,即标题
方案二:Awk工具实现
适合处理更复杂的文本格式,通过遍历字段定位拆分点:
awk '{ # 遍历字段找到"title"的起始位置 for(i=1; i<=NF; i++) { if ($i == "title") { title_pos = i break } } # 提取域名(第一个字段) domain = $1 # 提取关键词(从第2个字段到title前一个字段) keyword = "" for(j=2; j<title_pos; j++) { keyword = keyword $j " " } keyword = substr(keyword, 1, length(keyword)-1) # 移除末尾多余空格 # 提取标题(从title字段到末尾) title = "" for(j=title_pos; j<=NF; j++) { title = title $j " " } title = substr(title, 1, length(title)-1) # 移除末尾多余空格 # 输出结果 print "domain_name:" domain print "Key words:" keyword print "title:" title }' file.txt
注意事项
- 确保文本每行格式固定:域名是第一个字段,关键词以
keyword开头,标题以title开头,且title在每行中仅出现一次 - 两种方案均支持多个连续空格作为分隔符
内容的提问来源于stack exchange,提问作者st la
相关产品推荐
相关产品推荐

