Opening a file in write mode - bash

I have a file called a.txt. with values like
1
2
3
...
I want to overwrite this file but
echo "$var" >> a.txt
echo "$var1" >> a.txt
echo "$var2" >> a.txt
...
just appends. Using > is not useful as well. How can i overwrite with using >> operator in shell script?

You may want to use > for the first redirection and >> for subsequent redirections:
echo "$var" > a.txt
echo "$var1" >> a.txt
echo "$var2" >> a.txt

> truncates the file if it exists, and would do what you originally asked.
>> appends to the file if it exists.
If you want to overwrite the content of a file (not truncate it), use 1<>
e.g.:
[23:58:27 0 ~/tmp] $ echo foobar >a
[23:58:28 0 ~/tmp] $ cat a
foobar
[23:58:50 0 ~/tmp] $ echo -n bar 1<>a
[23:58:53 0 ~/tmp] $ cat a
barbar

In what way is using > not useful? That explicitly does what you want by overwriting the file, so use > for the first and then >> to append future values.

echo "$var
$var1
$var2" > a.txt
or
echo -e "$var\n$var1\n$var2" > a.txt

Related

How to append the rest of the command from a variable?

In the sample bellow, I would like to print text on the screen and also append this text into file, when the variable cpstdout is set to 1. Otherwise only print the text on screen. I need to have the echo part flexible to the append variable. Is there any way to correct my code?
#!/bin/ksh
cpstdout=1
if [ $cpstdout -eq 1 ]; then
append="| tee somefile"
else
append=""
fi
echo "test string" $append
Now the result is just like this:
./test.sh
test string | tee somefile
-no file is created of course
example of print function:
print_output(){
printf "\t/-------------------------------------------------\\ \n"
for i in "$#"; do
printf "\t| %-14s %-32s |\n" "$(echo $i | awk -F, '{print $1}')" "$(echo $i | awk -F, '{print $2}')"
shift
done
printf "\t\-------------------------------------------------/\n"
}
Define your appending command as a function:
output_with_append() {
tee -a somefile <<<"$1"
}
Then, in the if, set a variable to the appropriate outputting function:
if [ $cpstdout -eq 1 ]; then
output=output_with_append
else
output=echo
fi
Finally, use variable expansion to run the command:
$output "test_string"
Note that I've used tee -a since you said you wanted to append to a file and not overwrite it.
Setting cpstdout to $1 so we can control it through a command-line parameter:
cpstdout="$1"
A example session then looks like this:
$ ./test.sh 1
test_string
$ ./test.sh 1
test_string
$ cat somefile
test_string
test_string
$ ./test.sh 0
test_string
$ cat somefile
test_string
test_string

How to concatenate two files and write between them?

I am trying to achieve something like this with bash script:
c.txt:
contents of a.txt
###
contents of b.txt
Basically I want to write a constant string between the contents of two files and save to a new one without modifying the originals.
This was the closest I could get:
echo "###" >> a.txt|cat b.txt >> out.txt
Using - as a filename usually means to use standard input. Thus:
echo 'something' | cat a.txt - b.txt > new.txt
You could do it with three commands:
cat a.txt > out.txt
echo "###" >> out.txt
cat b.txt >> out.txt
And perhaps make a function out of it:
append_hash() { cat $1 > $3; echo "###" >> $3; cat $2 >> $3; }
Usage:
append_hash a.txt b.txt out.txt

How do I add to a column instead of a row using Bash Script and csv?

#!/bin/bash
# This file will gather who is information
while IFS=, read url
do
whois $url > output.txt
echo "$url," >> Registrants.csv
grep "Registrant Email:" output.txt >> Registrants.csv
done < $1
How do I get the grep output to go into a new column instead of a new row? I Want column 1 to have the echo, column 2 to have the grep, then go down to a new row.
You can disable the trailing newline on echo with the -n flag.
#!/bin/bash
# This file will gather who is information
while IFS=, read url
do
whois $url > output.txt
echo -n "$url," >> Registrants.csv
grep "Registrant Email:" output.txt >> Registrants.csv
done < $1
Use printf, then you don't have to worry if the "echo" you are using accepts options.
printf "%s" "$url,"
printf is much more portable than "echo -n".

What does the "done < $var" at the end of a loop do?

Just a simple question - I'm wondering what the following code is doing:
nlwd="$PWD/NLWD.txt"
cat /dev/null > $nlwd
echo "Enter filename to process:"
read name
while read line
do
uid="$(echo $line | cut -d, -f1)"
echo "$uid" | grep [0-9] >> $nlwd
done < $name
In particular, I'm wondering what the done < $name is doing.
It's taking a file name, reading that file line-by-line, and doing stuff with each line.
< is an input redirect, which means that the loop is taking its input from $name.
For example:
while read LINE
do
echo $LINE
done < $name
...is essentially the same as:
cat $name
In response to your comment, the cat /dev/null > $nlwd just empties out the file's contents. This time, it uses the > output redirection to take the contents of /dev/null (which is Linux's black hole file), and outputs that emptiness into file represented by the $nlwd variable. Here's a simpler example:
$> echo "something" > something.txt
$> cat something.txt
something
$> cat /dev/null > something.txt
$> cat something.txt
$>
Further reading: http://en.wikipedia.org/wiki//dev/null
It's an input redirection. The while loop (and thus each command in the while loop, specifically read) will take its standard input from the file named by $name.

How to append strings to the same line instead of creating a new line?

Redirection to a file is very usefull to append a string as a new line to a file, like
echo "foo" >> file.txt
echo "bar" >> file.txt
Result:
foo
bar
But is it also possible to redirect a string to the same line in the file ?
Example:
echo "foo" <redirection-command-for-same-line> file.txt
echo "bar" <redirection-command-for-same-line> file.txt
Result:
foobar
The newline is added by echo, not by the redirection. Just pass the -n switch to echo to suppress it:
echo -n "foo" >> file.txt
echo -n "bar" >> file.txt
-n do not output the trailing newline
An alternate way to echo results to one line would be to simply assign the results to variables. Example:
j=$(echo foo)
i=$(echo bar)
echo $j$i
foobar
echo $i $j
bar foo
This is particularly useful when you have more complex functions, maybe a complex 'awk' statement to pull out a particular cell in a row, then pair it with another set.

Resources