shell 脚本求指点

2022-07-09 22:13:56 +08:00
 wanchenyi
name: "fdfaas...."
id: "jsdkfksk...."
------
name: "fdfaas...."
id: "jsdkfksk...."
-----
name: "fdfaas...."
id: "jsdkfksk...."

求指点哈,我有一个文本,需要把里面的 name 和 id 对应的值取出来放到一条命令中去执行,每个 name 和 id 是不一样的(只是我为了方便打成一样的),----分隔的是一组,我猜的是可能要用 sed awk ,或者 grep,顺便问了句哪里可以找到提升使用 sed 和 awk 的教程或者资料,

1591 次点击
所在节点    问与答
22 条回复
ysc3839
2022-07-09 22:18:31 +08:00
如果都是这种很规整的,直接按行读取,然后用 grep 之类的提取 key 和 value ,遇到分隔就进行处理,应该没啥问题吧?
leonhao
2022-07-09 22:21:45 +08:00
哪这么麻烦,bash 脚本逐行遍历就完事了
wanchenyi
2022-07-09 22:25:59 +08:00
@ysc3839 我想到的就是这种,但我觉得这种要写的还要多一点
wanchenyi
2022-07-09 22:26:47 +08:00
@leonhao 主要是我简介了这个场景,这个内容已经是我用 grep 过滤出来的
ysc3839
2022-07-09 22:29:37 +08:00
@wanchenyi 个人没觉得多了,用 bash 的话还能直接进行正则匹配,不需要启动新进程了。
另外建议发原始数据。
thedrwu
2022-07-09 22:33:03 +08:00
sed 可以 N
TravisMtg
2022-07-10 09:57:31 +08:00
这个挺像 yaml 的,用 yq 来提取内容会不会方便点
ruidoBlanco
2022-07-10 10:07:57 +08:00
`cat aa.txt|awk -F\" '/^name:/ {name=$2} /^id:/ {id=$2} /^--/ {system("echo "name" "id)}'`
makelove
2022-07-10 10:29:50 +08:00
一般碰到这类复杂格式问题我都直接用调 python 用 heredoc 形式来写,用 bash 真是强人所难了
wxf666
2022-07-10 11:28:12 +08:00
不懂 awk 如何限制最多分割的列数(比如,按“:”分割,最多两列,最后一列可以包含任意个“:”),只能用正则来匹配了

假设 name 或 id 的值符合 json 的字符串规范

awk -v FPAT='(\\w+)|:|"(\\\\?.)*"' 'function output_dict() {if (length(dict)) {printf "%s\0%s\0", dict["name"], dict["id"]; delete dict }} /^\w/{dict[$1]=$3} /^-/{output_dict()} END{output_dict()}' | xargs -0 -n 2 echo


[输入]
name: "name1"
id: "id1"
------
id: "\"id2\": "
name: ": \"name2\""


[输出(要由后面的命令去转义了)]
"name1" "id1"
": \"name2\"" "\"id2\": "


[实际执行]
echo '"name1"' '"id1"'
echo '": \"name2\""' '"\"id2\": "'
wxf666
2022-07-10 11:37:45 +08:00
@ruidoBlanco

按 " 分割的话,值包含 " 就不好办了( name: "my name is \"xxx\"")

另外,最后一行不是------的话,最后一组值也没了
ruidoBlanco
2022-07-10 13:20:57 +08:00
@wxf666 shell 做这个,quick and dirty 是难以避免的。我那个,用了不到一分钟写出来,我觉得值了。

如果这么较真说 name 里面可能有引号,我也可以较真说 name 可以有重复。最后一行不是----确实是个 bug ,不过很好改。
wxf666
2022-07-10 14:11:36 +08:00
@ruidoBlanco 我是 v 站 新人,不太熟悉这儿的风气,不知道回答问题是否该考虑全一点,还是大致给个方向即可

我觉得,字符串里有 " 是合理且可预见的情况,还是该做处理的,仍属于帖子“提取对应值”主题范畴

(所以,只是“答得有没有更全面一点”的区别?)

“name 可以有重复”,这是上一层的工作了吧。另外,楼主也说了“每个 name 和 id 是不一样的”
ilotuo
2022-07-10 15:30:00 +08:00
用 python 就简单多了..

for line in f.readlines():
if line.startwith("name"):
name = re.findall(r".*\"(.+?)\"",line)[0]
else if line.startwith("id"):
id = re.findall(r".*\"(.+?)\"",line)[0]
else if line.startwith("---"):
os.system('xxxxx')
wanchenyi
2022-07-10 21:04:50 +08:00
@wxf666
@ruidoBlanco name 没有引号,应该是 uuid 之类的,
wanchenyi
2022-07-10 21:05:34 +08:00
@ilotuo 感谢你哦,我也是写 Python ,笑哭,这里有一些场景,限制 ,还是得上 shell ,
wanchenyi
2022-07-10 21:06:38 +08:00
@ysc3839 那么多数据记不住,哈哈
wanchenyi
2022-07-10 21:06:56 +08:00
@TravisMtg 我去了解哈
wanchenyi
2022-07-10 21:07:29 +08:00
@ruidoBlanco 感谢
wanchenyi
2022-07-10 21:08:51 +08:00
感谢各位的围观,8 楼的老哥的答应是我想要的答案。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/865176

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX