How to concatenate two files and write between them? - bash

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

Related

Using bash script, How to add a comment in the beginning of each file to all files in a folder

How do i Add a comment in the beginning of each file with file name the folder name. Need to do this to all files in a folder
eg:
directory:Chapter01
Files: file1_1
Sample inpput:
cat file1_1
hello hello hello
Expected output:
cat file1_1
####Directory Name:Chapter01, File Name: file1_1
hello hello hello
This untested snippet should work.
for i in *
do
echo "Processing ${i}"
echo "Directory Name:$(pwd), File name:${i}" > ${i}.tmp
cat ${i} >> ${i}.tmp
echo "Created ${i}"
# mv ${i}.tmp ${i}
done
This will create a .tmp corresponding to each file in your directory. The commented out mv will change the original file. You can do that if you're happy with the results.
awk to the rescue!
$ awk 'FNR==1{n=split(FILENAME, a, "/");
print "# Dir name: " a[n-1] " File name: " a[n] > FILENAME}
{print > FILENAME}' path/to/files/*
as a side benefit, it will skip empty files. It will print the immediate parent directory "files" and the actual filename. You need to run at least one dir up.
Use an editor to change the current files.
dirname=${PWD##*/}
for file in inp*; do
ed -s "${file}" <<EOF >/dev/null
1
a
####Directory Name:${dirname}, File Name: ${file}
.
w
q
EOF
done

Control if a new file incoming in a folder with "comm"

I'm using a comm in a infinite cycle for view if a new file incoming in a folder, but i not have difference from 2 files but for example if incominig file "a" i view in output:
a a.out a.txt b.txt test.cpp testshell.sh
a.out a.txt b.txt test.cpp testshell.sh
my Code is this:
#! /bin/ksh
ls1=$(ls);
echo $ls1 > a.txt;
while [[ 1 > 0 ]] ; do
ls2=$(ls);
echo $ls2 > b.txt;
#cat b.txt;
#sort b.txt > b.txt;
#diff -u a.txt b.txt;
#diff -a --suppress-common-lines -y a.txt b.txt
comm -3 a.txt b.txt;
printf "\n";
ls1=$ls2;
echo $ls1 > a.txt;
#cat a.txt;
#sleep 2;
#sort a.txt > a.txt;
done
THANKS
#! /bin/ksh
set -vx
PreCycle="$( ls -1 )"
while true
do
ThisCycle="$( ls -1 )"
echo "${PreCycle}${ThisCycle}" | uniq
PreCycle="${ThisCycle}"
sleep 10
done
give add and removed difference but without use of file. Could directly give new file same way but uniq -f 1 failed (don't understand why) when used on list prefixed by + and - depending of source

Add prefix to every line in text in bash

Suppose there is a text file a.txt e.g.
aaa
bbb
ccc
ddd
I need to add a prefix (e.g. myprefix_) to every line in the file:
myprefix_aaa
myprefix_bbb
myprefix_ccc
myprefix_ddd
I can do that with awk:
awk '{print "myprefix_" $0}' a.txt
Now I wonder if there is another way to do that in shell.
With sed:
$ sed 's/^/myprefix_/' a.txt
myprefix_aaa
myprefix_bbb
myprefix_ccc
myprefix_ddd
This replaces every line beginning ^ with myprefix_. Note that ^ is not lost, so this allows to add content to the beginning of each line.
You can make your awk's version shorter with:
$ awk '$0="myprefix_"$0' a.txt
myprefix_aaa
myprefix_bbb
myprefix_ccc
myprefix_ddd
or passing the value:
$ prefix="myprefix_"
$ awk -v prefix="$prefix" '$0=prefix$0' a.txt
myprefix_aaa
myprefix_bbb
myprefix_ccc
myprefix_ddd
It can also be done with nl:
$ nl -s "prefix_" a.txt | cut -c7-
prefix_aaa
prefix_bbb
prefix_ccc
prefix_ddd
Finally: as John Zwinck explains, you can also do:
paste -d'' <(yes prefix_) a.txt | head -n $(wc -l a.txt)
on OS X:
paste -d '\0' <(yes prefix_) a.txt | head -n $(wc -l < a.txt)
Pure bash:
while read line
do
echo "prefix_$line"
done < a.txt
For reference, regarding the speed of the awk, sed, and bash solution to this question:
Generate a 800K input file in bash:
line="12345678901234567890123456789012345678901234567890123456789012345678901234567890"
rm a.txt
for i in {1..10000} ; do
echo $line >> a.txt
done
Then consider the bash script timeIt
if [ -e b.txt ] ; then
rm b.txt
fi
echo "Bash:"
time bashtest
rm b.txt
echo
echo "Awk:"
time awktest
rm b.txt
echo
echo "Sed:"
time sedtest
where bashtest is
while read line
do
echo "prefix_$line" >> b.txt
done < a.txt
awktest is:
awk '$0="myprefix_"$0' a.txt > b.txt
and sedtest is:
sed 's/^/myprefix_/' a.txt > b.txt
I got the following result on my machine:
Bash:
real 0m0.401s
user 0m0.340s
sys 0m0.048s
Awk:
real 0m0.009s
user 0m0.000s
sys 0m0.004s
Sed:
real 0m0.009s
user 0m0.000s
sys 0m0.004s
It seems like the bash solution is much slower..
You can also use the xargs utility:
cat file | xargs -d "\n" -L1 echo myprefix_
The -d option is used to allow input line with trailing blanks (related to -L spec).

Echo data into two files

How do I insert data into files at a time?
Consider if I have like data below:
echo "hi" >> file1
echo "hi" >> file2
How can I redirect the same "hi" into file1 and file2 simultaneously?
$ echo hi | tee -a file1 file2
See the tee manpage.

Opening a file in write mode

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

Resources