如何用awk实现点击切换显示calcurse日历文件首行后的事件行?
解决calcurse事件文件内容提取与polybar轮显需求
问题说明
我有一个calcurse生成的日历事件文件,内容如下:
01/23/23: * Homework * Sports
需要在i3wm的polybar中做一个按钮,点击时依次显示首行之后的每一行事件(因宽度限制每次只显示一行)。之前尝试用head和awk组合测试:
head -1 myfile | awk '{print $1}' # 输出01/23/23: head -2 myfile | awk '{print $2}' # 输出Homework
但执行head -3 myfile | awk '{print $3}'无法输出Sports,需要解决这个问题并实现需求。
问题原因
你之前的命令逻辑错误:head -3会输出文件前三行,而awk '{print $3}'是取每行的第三个字段,但第三行内容是* Sports,只有两个字段(*和Sports),所以$3不存在,自然取不到内容。而且这种逐行head的方式完全不适合轮显需求。
解决方案
1. 正确提取事件内容的命令
要跳过首行,提取后续每行的事件文本,可以用以下两种方式:
- awk方式:跳过第一行,截取每行从第4个字符开始的内容(因为每行开头是
*,共3个字符):
awk 'NR>1 {print substr($0, 4)}' myfile
- sed方式:删除第一行,再替换掉开头的
*和空格:
sed '1d; s/^\s*\*\s*//' myfile
这两个命令都会输出:
Homework Sports
2. polybar轮显脚本实现
要实现点击按钮依次切换事件,需要一个脚本来记录当前显示的事件索引,每次点击更新索引并输出对应事件:
#!/bin/bash # 替换为你的事件文件路径 EVENT_FILE="$HOME/.calcurse/events.txt" # 临时文件用来存储当前显示的事件索引 STATE_FILE="/tmp/polybar_event_index" # 初始化索引文件(如果不存在则设为1) if [ ! -f "$STATE_FILE" ]; then echo 1 > "$STATE_FILE" fi # 获取总事件数量 TOTAL_EVENTS=$(awk 'NR>1' "$EVENT_FILE" | wc -l) # 获取当前索引 CURRENT_INDEX=$(cat "$STATE_FILE") # 提取当前要显示的事件(NR>1跳过首行,NR-1 == CURRENT_INDEX-1对应第N个事件) CURRENT_EVENT=$(awk -v idx="$CURRENT_INDEX" 'NR>1 && (NR-1) == (idx-1) {print substr($0, 4)}' "$EVENT_FILE") # 计算下一个索引,循环轮显 NEXT_INDEX=$((CURRENT_INDEX % TOTAL_EVENTS + 1)) echo "$NEXT_INDEX" > "$STATE_FILE" # 输出事件内容给polybar echo "$CURRENT_EVENT"
3. polybar模块配置
在你的polybar配置文件中添加以下模块:
[module/calcurse-events] type = custom/script # 替换为你的脚本路径 exec = /path/to/your/event_script.sh # 点击左侧执行脚本切换事件 click-left = /path/to/your/event_script.sh # 关闭自动刷新,只在点击时更新 interval = 0 format = <label> label = %output% # 可选:添加图标 ; label = %output%
把脚本设为可执行权限:
chmod +x /path/to/your/event_script.sh
重启polybar后,点击这个模块就能依次切换显示每个事件了。
内容的提问来源于stack exchange,提问作者mle0312
相关产品推荐
相关产品推荐

