I need to read a file with bash and remove the request line? Some similar to pop/push functions.
How can i do it?
sed
would do the job finely!As rightly pointed by a comment from @Lee Netherton, the when running sed for inplace editing, the use of backups are strongly recommended! (Of course, once done, your script have to test the success of sed
command before continuing... )
So let quickly build a test file:
printf "Line #%2d\n" {1..7} >file
As a real push/pop, the following command return the wanted line and drop them from the named file.
sed -e \$$'{w/dev/stdout\n;d}' -i~ file
Line # 7
then
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
(removing nth line)
lineNum=3
sed -e $lineNum$'{w/dev/stdout\n;d}' -i~ file
Line # 4
printf -v val "Line #%2d" 28
echo "$val" >>file
Nota: This could be done by using sed
anyway:
sed -e "\$a$val" -i~ file
(Where $a
IS NOT a variable, but the sed location $
, which mean at end of file and the a
command, which mean append after current line)
printf -v val "Line #%2d" 62
sed -e 1i"$val" -i~ file
Then finally
cat file
Line #62
Line # 2
Line # 3
Line # 5
Line # 6
Line #28
Of course, the goal is to retrieve them into a variable. Depending of if you are using bash or another POSIX shell, you could use one of:
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
Happy new year!
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"; }
Nota: Line printf ${2+-v} $2 "%s${n[${2+2}]}" "$v"
is a kind of trick I use often in my functions. This line will populate a variable, if submited as second argument. If else this line will add a newline and print to STDOUT
.
Little run sample:
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"
(The variable myvar didn't contain newline.)
And ( I can't resist! ;-):
fpop file myvar
echo $((9? ${myvar#*#} :-b))
42
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With