Bash:文件中的弹出线条

Rfr*_*ile 4 bash line

我需要用bash读取文件并删除请求行?有些类似于pop/push功能.

我该怎么做?

F. *_*uri 14

对!sed会做得很好!

介绍

正如@Lee Netherton的评论所正确指出的那样,在运行进行就地编辑时,强烈建议使用备份!(当然,一旦完成,你的脚本必须sed在继续之前测试命令的成功...)

测试用例

所以让我们快速构建一个测试文件:

printf "Line #%2d\n" {1..7} >file
Run Code Online (Sandbox Code Playgroud)

对于pop(从堆栈顶部):

作为一个真正的push/pop,以下命令返回所需行并将其从命名文件中删除.

sed -e \$$'{w/dev/stdout\n;d}' -i~ file
Line # 7
Run Code Online (Sandbox Code Playgroud)

然后

cat file
Line # 1
Line # 2
Line # 3
Line # 4
Line # 5
Line # 6
Run Code Online (Sandbox Code Playgroud)

对于移位(从栈的底部):

sed -e 1$'{w/dev/stdout\n;d}' -i~ file
Line # 1
Run Code Online (Sandbox Code Playgroud)

用于拼接(堆栈中的随机访问)

(删除第n行)

lineNum=3
sed -e $lineNum$'{w/dev/stdout\n;d}' -i~ file
Line # 4
Run Code Online (Sandbox Code Playgroud)

(向堆栈的顶部):

printf -v val "Line #%2d" 28
echo "$val" >>file
Run Code Online (Sandbox Code Playgroud)

Nota:sed无论如何都可以这样做:

sed -e "\$a$val" -i~ file
Run Code Online (Sandbox Code Playgroud)

(其中$aIS不是变量,而是sed位置$,表示文件末尾a命令,表示在当前行后追加)

for unshift(到堆栈底部):

printf -v val "Line #%2d" 62
sed -e 1i"$val" -i~ file
Run Code Online (Sandbox Code Playgroud)

然后最后

cat file
Line #62
Line # 2
Line # 3
Line # 5
Line # 6
Line #28
Run Code Online (Sandbox Code Playgroud)

变成一个变量

当然,目标是将它们检索到变量中.根据您使用的是还是其他POSIX ,您可以使用以下方法之一:

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
Run Code Online (Sandbox Code Playgroud)

新增2018年新增

新年快乐!

示例,简单的bash函数:

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; }
Run Code Online (Sandbox Code Playgroud)

Nota: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"
Run Code Online (Sandbox Code Playgroud)

(变量myvar不包含换行符.)

而且(我无法抗拒!;-):

fpop file myvar
echo $((9? ${myvar#*#} :-b))
42
Run Code Online (Sandbox Code Playgroud)


Chr*_*our 0

您可以使用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
Run Code Online (Sandbox Code Playgroud)

但是,您将无法push恢复这些线路。