我需要用 bash 读取文件并删除请求行吗?一些类似于弹出/推送功能。
我该怎么做?
sed
会做得很好!正如@Lee Netherton的评论所正确指出的那样,在运行sed进行就地编辑时,强烈建议使用备份!(当然,一旦完成,您的脚本必须sed
在继续之前测试命令是否成功......)
所以让我们快速构建一个测试文件:
printf "Line #%2d\n" {1..7} >file
作为真正的 push/pop,以下命令返回所需的行并将它们从命名文件中删除。
sed -e \$$'{w/dev/stdout\n;d}' -i~ file
Line # 7
然后
cat file
Line # 1
Line # 2
Line # 3
Line # 4
Line # 5
Line # 6
sed -e 1$'{w/dev/stdout\n;d}' -i~ file
Line # 1
(删除第n行)
lineNum=3
sed -e $lineNum$'{w/dev/stdout\n;d}' -i~ file
Line # 4
printf -v val "Line #%2d" 28
echo "$val" >>file
注意:这可以通过使用来完成sed
:
sed -e "\$a$val" -i~ file
(其中$a
不是变量,而是sed位置$
,这意味着在文件末尾和a
命令,这意味着在当前行之后追加)
printf -v val "Line #%2d" 62
sed -e 1i"$val" -i~ file
然后终于
cat file
Line #62
Line # 2
Line # 3
Line # 5
Line # 6
Line #28
当然,目标是将它们检索到变量中。根据您使用的是bash还是其他POSIX shell,您可以使用以下之一:
lastline=`sed -e \\\$$'{w/dev/stdout\n;d}' -i~ file`
echo $lastline
Line #28
lastline=$(sed -e \$$'{w/dev/stdout\n;d}' -i~ file)
echo $lastline
Line # 6
read lastline < <(sed -e \$$'{w/dev/stdout\n;d}' -i~ file)
echo $lastline
Line # 5
新年快乐!
fpop() { local v n=$'\n';read -r v < <(
sed -e $'${w/dev/stdout\n;d}' -i~ "$1")
printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
}
fshift() { local v n=$'\n';read -r v < <(
sed -e $'1{w/dev/stdout\n;d}' -i~ "$1")
printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
}
fsplice() {
[ "$2" ] || return ; local v n=$'\n';read -r v < <(
sed -e $2$'{w/dev/stdout\n;d}' -i~ "$1");
printf ${3+-v} $3 "%s${n[${3+3}]}" "$v"
}
fpush() { sed -e "\$a$2" -i~ "$1"; }
funshift() { sed -e "1i$2" -i~ "$1"; }
注意:Line是我在函数中经常使用printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
的一种技巧。如果作为第二个参数提交,此行将填充一个变量。否则,此行将添加换行符并打印到STDOUT
.
小运行示例:
printf "Line #%2d\n" {3..12} >file
fpop file
Line #12
fpop file myvar
echo $myvar
Line #11
fshift file
Line # 3
fshift file myvar
echo $myvar
Line # 4
fsplice file 3
Line # 7
fsplice file 3 myvar
echo $myvar
Line # 8
funshift file "Line # 192"
fpush file "Line # 42"
cat file
Line # 192
Line # 5
Line # 6
Line # 9
Line #10
Line # 42
declare -p myvar
declare -- myvar="Line # 8"
(变量myvar不包含换行符。)
而且(我无法抗拒!;-):
fpop file myvar
echo $((9? ${myvar#*#} :-b))
42
sed 是面向流的,你可以使用适合编辑文件的 ed。
#/usr/bin/sh
ed -s filename <<EDSCRIPT
1p
d
wq
EDSCRIPT
如果您想做其他事情,
1,3
则适用于第 1 行至第 3
$
行。适用于最后一行。
您可以使用sed
删除与给定模式匹配的特定行号或行:
$ cat file
line 1
line 2
line 3
line 4
line 5
$ sed -i '3d' file # Delete the 3rd line
line 1
line 2
line 4
line 5
$ sed -i '/^line 4$/d' file # Delete the line that matches the pattern
line 1
line 2
line 3
line 5
$ sed '$d' file # Delete the last line in the file
line 1
line 2
line 3
line 4
但是,您将无法push
返回这些行。