echo from lines of a file - bash

i have a file "myfile.txt" that have the next content:
hola mundo
hello word
and i want work with every line
for i in `cat myfile.txt`; do echo $i; done
i hope this give me
hola mundo
hello word
firts one line, then the other, but get
hola
mundo
hello
word
as I can demanding results until newline instead of each space?
ty all

That's better
cat myfile.txt | while read line; do
echo "$line"
done
or even better (doesn't launch other processes such as a subshell and cat):
while read line; do
echo "$line"
done < myfile.txt
If you prefer oneliners, it's obviously
while read line; do echo "$line"; done < myfile.txt

Related

Read from a file and stdin in Bash

I would like to know if I can write a shell script that accepts two arguments simultaneously, one from a file and the another one from stdin. Could you give some example please?.
I trying
while read line
do
echo "$line"
done < "${1}" < "{/dev/stdin}"
But this does not work.
You can use cat - or cat /dev/stdin:
while read line; do
# your code
done < <(cat "$1" -)
or
while read line; do
# your code
done < <(cat "$1" /dev/stdin)
or, if you want to read from all files passed through command line as well as stdin, you could do this:
while read line; do
# your code
done < <(cat "$#" /dev/stdin)
See also:
How to read from a file or stdin in Bash?
This topic seems to be helpful here:
{ cat $1; cat; } | while read line
do
echo "$line"
done
Or just
cat $1
cat
if all you're doing is printing the content

sed DON'T remove extra whitespace

It seems everybody else wants to remove any additional whitespace, however I have the opposite problem.
I have a file, call it some_file.txt that looks like
a b c d
and some more
and I'm reading it line-by-line with sed,
num_lines=$(cat some_file.txt | wc -l)
for i in $(seq 1 $num_lines); do
echo $(sed "${i}q;d" $file)
string=$(sed "${i}q;d" $file)
echo $string
done
I would expect the number of whitespace characters to stay the same, however the output I get is
a b c d
a b c d
and some more
and some more
So it seems that the problem is with sed removing the extra whitespace between chars, anyway to fix this?
Have a look at this example:
$ echo Hello World
Hello World
$ echo "Hello World"
Hello World
sed is not your problem, your problem is that bash removes the whitespaces when passing the output of sed into echo.
You just need to surround whatever echo is supposed to print with double quotation marks. So instead of
echo $(sed "${i}q;d" $file)
echo $string
You write
echo "$(sed "${i}q;d" $file)"
echo "$string"
The new script should look like this:
#!/usr/bin/env bash
file=some_file.txt
num_lines=$(cat some_file.txt | wc -l)
for i in $(seq 1 $num_lines); do
echo "$(sed "${i}q;d" $file)"
string=$(sed "${i}q;d" $file)
echo "$string"
done
prints the correct output:
a b c d
a b c d
and some more
and some more
However, if you just want to go through your file line by line, I strongly recommend something like this:
while IFS= read -r line; do
echo "$line"
done < some_file.txt
Question from the comments: What to do if you only want 33 lines starting from line x. One possible solution is this:
#!/usr/bin/env bash
declare -i s=$1
declare -i e=${s}+32
sed -n "${s},${e}p" $file | while IFS= read -r line; do
echo "$line"
done
(Note that I would probably include some validation of $1 in there as well.)
I declare s and e as integer variables, then even bash can do some simple arithmetic on them and calculate the actual last line to print.

Failed to echo on the same line after using sed

I am reading a text file with the following code and I want to echo the output on the same line on screen. Preceding to that, I want to do some trimming with sed but at the end I failed to echo the output on the same line.
while read line; do {
var="$(echo $line | sed 's/<[^>]*>//g')";
echo -n "$var"
} done < file.txt
So if I echo -n "$line" it prints the output on the same line but when `sed' comes in it failed to do so. What is it that I am doing wrong ?

print line without the first word into a variable

This is my code
title=""
line=""
fname=$1
numoflines=$(wc -l < $fname)
for ((i=2 ; i<=$numoflines ; i++))
do
...
done
In the for loop i want to print the first word of every line into $title
and the rest of the line without the first word into $line
(using bash)
tnx
I am assuming that by print to a variable you mean add the contents of each line to the variable. To do this, you can use the bash built-in function read:
while read -r t l; do title+="$t"; line+="$l"; done < "$fname"
This will add the first word of every line to $title and the rest of the line to $line.
You can do some like this:
echo "$fname"
This is my line.
My cat is green.
title=$(awk '{print $1}' <<< "$fname")
line=$(awk '{$1="";sub(/^ /,"")}1' <<< "$fname")
echo "$title"
This
My
echo "$line"
is my line.
cat is green.
Alternative approach using the cut command:
file="./myfile.txt"
title=$(cut -f1 -d ' ' "$file")
line=$(cut -f2- -d ' ' "$file")
#check print
pr -tm <(echo -e "TITLES\n$title") <(echo -e "LINES\n$line")
for the next myfile.txt
My cat is green.
Green cats are strange.
prints
TITLES LINES
My cat is green.
Green cats are strange.
do
Tempo="$( sed -n "${i} {s/^[[:blank:]]*\([^[:blank:]]*\)[[:blank:]]*\(.*\)/title='\1';line='\2'/p;q;}" ${fname} )"
eval "${Tempo}"
done
# or
do
sed -n "${i} {p;q;}" | read Line Title
# but this does not keep content available on each OS/shell
done

Why the variable is cut while reading a file?

This is my code to read a file line by line:
IFS=$'\n'
myfile="$1"
i=0
while read line; do
echo "Line # $i: '$line'"
let i++
done < "$myfile"
This is the file passed as parameter
Hello
stack
overflow
friends
I execute it like this: test.sh input.txt and I get this result:
'ine # 0: 'Hello
'ine # 1: 'stack
'ine # 2: 'overflow
'ine # 3: 'friends
As you see, The fisrt character is replaced by a quote. And the quote of the final of the line does not appear. Whats going on here? I can't see the mistake? Any idea?
Most likely you have \r before end of line in your input file.
You can test same by using:
cat -vte file
This will show ^M$ in the end of file has dos carriage return \r.
You can use this script to read your file correctly:
i=1
while IFS=$'\r' read -r line; do
echo "Line # $i: '$line'"
let i++
done < "$myfile"
OR else convert your file into unix file using:
dos2unix file
OR If you don't wish to actually save the file stripped off of \r, you can also use:
while read line; do
........# your code as-is
done < <( tr -d '\r' < "$myfile")

Resources