我有一个包含很多步骤的说明文件。我想在 shell 中查看单个所需的步骤,而无需图形环境。正如指出的那样,我现在正在做什么阿莱莫尔,用于sed
提取我想要查看的步骤号和下一个步骤号内的内容。
cat file | sed -n '/12/,/13/p'
第 12 步:某事
commands to execute
第 13 步:其他事
我想要让它完全按照我想要的方式做的是省略最后一行:所做的sed
是从第一次出现到第二次打印,包括那些。我想避免第二个,从输出中删除最后一行并打印
第12步:一些东西
commands to execute
我如何修改我的命令来实现这一目标?我不希望有额外的命令、管道等。如果可能的话,我只想修改sed
我的使用方式(或者同样简单地使用其他一些工具,例如grep
),将第一个模式与第二个模式区分开来,例如“打印一个但省略另一个”。
另外,我希望命令尽可能简单,这样我就可以不费力地记住它,并在很短的时间内写出来。
答案1
Don_crissti 在评论中给了你一个解决方案(我将遵循他的文件命名约定):
sed -n '/12/,/13/{/13/!p}' UUoC.txt
这将选择文件中从第一行12
到第一行的所有行,并打印它们,除非它们匹配(就是这样)。13
UUoC.txt
13
/13/!p
另一种方法是使用head
丢弃最后一行:
sed -n '/12/,/13/p' file.txt | head -n -1
答案2
don_crissti 和 terdon 完成了所有艰苦的工作;我看到这个问题,想建议使用 shell 函数来进一步减少打字/记忆,也许还可以增加一些灵活性。在输入时,我还冒昧地收紧了一些正则表达式,以避免误报。
这是外壳函数:
function step () (
STEPS=./steps.txt
start=$1
stop=$((start+1))
sed -n "/^Step $start:/,/^Step $stop:/ { /^Step $stop:/ !p }" $STEPS
)
显然,您可以随意命名它;step
根据说明文件的措辞,我似乎很直观。调整STEPS
变量为实际指令文件的完整路径;这样,您就不必记住或打字! -- 命令行中该文件的路径。我让该函数使用子 shell——主体周围的括号而不是大括号——因为我不想用 STEPS、start 和 stop 变量污染 shell 的命名空间。如果创建子 shell 比三个新变量更麻烦,请随意将第二组括号更改为大括号。
我对 don 和 terdon 使用的正则表达式做了两件基本的事情:
- 强制比赛从行首开始,并且
- 要求它包含单词“Step”,后跟数字,然后是冒号。
我做了这两件事,因为我可以想象指令文件中可能包含数字commands to execute
,因此导致更简单的正则表达式错误匹配。
这是我使用的“魔鬼代言人”steps.txt 文件:
Step 1: one
commands to execute
Step 2: two
commands to execute
commands to execute
Step 3: three
commands to execute skip to Step 7
Step 4: four
commands to execute not step 5
commands to execute
commands to execute
commands to execute
Step 5: five
commands to execute
commands to execute
commands to execute skip to Step 6:
commands to execute
Step 6: six
commands to execute
Step 7: seven
commands to execute
Step 8: eight
commands to execute
Step 9: nine
commands to execute
Step 10: ten
commands to execute
Step 11: eleven
commands to execute
Step 12: something
commands to execute
commands to execute
Step 13: something else
commands to execute
...以及测试工具的结果(输出为step 14
空):
$ for step in $(seq 1 14); do step $step; echo; done
Step 1: one
commands to execute
Step 2: two
commands to execute
commands to execute
Step 3: three
commands to execute skip to Step 7
Step 4: four
commands to execute not step 5
commands to execute
commands to execute
commands to execute
Step 5: five
commands to execute
commands to execute
commands to execute skip to Step 6:
commands to execute
Step 6: six
commands to execute
Step 7: seven
commands to execute
Step 8: eight
commands to execute
Step 9: nine
commands to execute
Step 10: ten
commands to execute
Step 11: eleven
commands to execute
Step 12: something
commands to execute
commands to execute
Step 13: something else
commands to execute