Deleting echo line in bash - bash

var=ab
echo -n "$var"
Output: ab
var=abc
echo "$var"
Output: ababc
I want to delete the first ab and replace it by abc
How would I do that?
Regards, intelinside

Perhaps you are looking for something like:
var=ab
echo -n "$var"
var=abc
echo -e "\r$var"
This doesn't actually delete anything, but merely moves the cursor to the beginning of the line and overwrites. If the text being written is too short, the content of the previous write will still be visible. You can either write spaces over the old text (very easy and portable):
printf "\r%-${COLUMNS}s" "$var"
or use some terminal escape sequences to delete the old text (not portable):
echo -e "\r$var\033[K"
to move to the beginning of the line, write new text, and then delete from the cursor to the end of the line. (This may not work, depending on the terminal.)

Related

Split and display file line in bash

I have a simple bash script and I don't understand the return value.
My script
#!bin/bash
string=$(head -n 1 test.txt)
IFS=":"
read -r pathfile line <<< "$string"
echo "left"$line"right"
And my test.txt
filepath:file content
others lines
...
I have this return on the console.
rightfile content
The problem isn't when file only have 1 line.
I don't know why I don't have left value right to result.
Your input file has MSWin line ends (\x0D\x0A). Therefore, \x0D becomes part of $line and when printed, it moves the cursor back to the beginning, so $line"right" overwrites it.
Run dos2unix or fromdos on the input file to fix it.
BTW, you don't need to quote left and right. Quoting the variable might be needed, though.
echo left"$line"right

Unix Bash content of a file as argument stops at first line

I'm having an issue in something that seems to be a rookie error, but I can't find a way to find a solution.
I have a bash script : log.sh
which is :
#!/bin/bash
echo $1 >> log_out.txt
And with a file made of filenames (taken from the output of "find" which names is filesnames.txt and contains 53 lines of absolute paths) I try :
./log.sh $(cat filenames.txt)
the only output I have in the log_out.txt is the first line.
I need each line to be processed separately as I need to put them in arguments in a pipeline with 2 softwares.
I checked for :
my lines being terminated with /n
using a simple echo without writing to a file
all the sorts of cat filenames.txt or (< filenames.txt) found on internet
I'm sure it's a very dumb thing, but I can't find why I can't iterate more than one line :(
Thanks
It is because your ./log.sh $(cat filenames.txt) is being treated as one argument.
while IFS= read -r line; do
echo "$line";
done < filenames.txt
Edit according to: https://mywiki.wooledge.org/DontReadLinesWithFor
Edit#2:
To preserve leading and trailing whitespace in the result, set IFS to the null string.
You could simplify more and skip using explicit variable and use the default $REPLY
Source: http://wiki.bash-hackers.org/commands/builtin/read
You need to quote the command substitution. Otherwise $1 will just be the first word in the file.
./log.sh "$(cat filenames.txt)"
You should also quote the variable in the script, otherwise all the newlines will be converted to spaces.
echo "$1" >> log_out.txt
If you want to process each word separately, you can leave out the quotes
./log.sh $(cat filenames.txt)
and then use a loop in the script:
#!/bin/bash
for word in "$#"
do
echo "$word"
done >> log_out.txt
Note that this solution only works correctly when the file has one word per line and there are no wildcards in the words. See mywiki.wooledge.org/DontReadLinesWithFor for why this doesn't generalize to more complex lines.
You can iterate with each line.
#!/bin/bash
for i in $*
do
echo $i >> log_out.txt
done

bash command line append to variable will prepend instead

in shell scripts I usually append a string to variable with "${variable} end". However, I have a file "file.txt" in which I want all lines to be appended by "end". So command line I do, for instance, for i in `cat file.txt`; do echo "${i} end"; done. But the word "end" (pluse the space) will not be appended but appended. The same thing happends when I use a while loop. Could anybody tell me what is going on right there? I am using GNU bash version 4.2.37 on LinuxMint13 64bit (both Cinammon and Mate).
Thank you for any help!
You should use a while loop instead of a for loop, as explained here.
while IFS= read -r line
do
echo "$line end"
done < "file.txt"
It may just be your syntax - don't forget do. That is:
for i in `cat file.txt`; do echo "${i} end"; done
If you're asking how to make a new file with "end" appended to each line, try this:
for i in `cat file.txt`; do echo "${i} end" >> some_new_file; done
Is using a loop the only option? If all you want to do is append something to the end of every line, it's probably easier to use sed:
sed -ie 's/.*/& end/' file.txt

Echoing a backspace

Is it possible to echo a backspace in bash?
Something like
echo $'stack\b'
Shouldn't output stac? Or I'm missing something?
More specifically, I'd like to use that in:
ls | wc -l; echo $'\b items'
\b makes the cursor move left, but it does not erase the character. Output a space if you want to erase it.
For some distributions you may also need to use -e switch of echo:
-e enable interpretation of backslash escapes
So it will look like
echo -e 'stack\b '
Also, files=(*) ; echo "${#files[#]} items".
So to answer the actual question about backspaces this will simulate a backspace:
echo -e "\b \b"
It will move the character back one, then echo a space overwriting whatever character was there, then moving back again - in effect deleting the previous character. It won't go back up a line though so the output before that should not create a new line:
echo -n "blahh"; echo -e "\b \b"
It is not exactly what you're asking for, but also, in the line of Ignacio's answer, you could use for this case:
echo "$(ls | wc -l) items"
AFAIK you cannot print a character that deletes the one before, not even printing the char whose hexadecimanl number correspoonds to backspace. You can move back and print a blank space to delete, though. With cput you can do many things and print wherever you want in the screen.

Cat with new line

My input file's contents are:
welcome
welcome1
welcome2
My script is:
for groupline in `cat file`
do
echo $groupline;
done
I got the following output:
welcome
welcome1
welcome2
Why doesn't it print the empty line?
you need to set IFS to newline \n
IFS=$"\n"
for groupline in $(cat file)
do
echo "$groupline";
done
Or put double quotes. See here for explanation
for groupline in "$(cat file)"
do
echo "$groupline";
done
without meddling with IFS, the "proper" way is to use while read loop
while read -r line
do
echo "$line"
done <"file"
Because you're doing it all wrong. You want while not for, and you want read, not cat:
while read groupline
do
echo "$groupline"
done < file
The solution ghostdog74 provided is helpful, but has a flaw.
IFS could not use double quotes (at least in Mac OS X), but can use single quotes like:
IFS=$'\n'
It's nice but not dash-compatible, maybe this is better:
IFS='
'
The blank line will be eaten in the following program:
IFS='
'
for line in $(cat file)
do
echo "$line"
done
But you can not add double quotes around $(cat file), it will treat the whole file as one single string.
for line in "$(cat file)"
If want blank line also be processed, using the following
while read line
do
echo "$line"
done < file
Using IFS=$"\n" and var=$(cat text.txt) removes all the "n" characters from the output echo $var

Resources