Shell Script for merging multiple text files into One file fails - bash

Need help in merging multiple text files in to one file,
When am doing this through shell script it is changing the alignment of the file.
Eg : File 1 has data as below :
Hello world
Hello World1
Hello World2
File 2 has data as below :
Hello New World
Hello New World 2
Resultant file created through shell script post merging :
Hello world Hello Wor
ld Hello world2
the lines of the files are clubbed together.
This shell script is executed on the AS400 system
Code used :
cat *.${3} >> ${2}

Try this..
cat file1
`Hello world
Hello World1
Hello World2`
cat file1 >> file3
cat file3
Hello world
Hello World1
Hello World2
cat file2
Hello New World
Hello New World 2
cat file2 >> file3
cat file3
Hello world
Hello World1
Hello World2
Hello New World
Hello New World 2
Another way out is :$ sed -n wfile.merge file1.txt file2.txt

I will assume that :
1 - ${3} is the extension of the files you want to concatenate, and therefore *.${3} is the names of all the source files.
2 - The result you posted is not actually an exact output. (there is no "world2" word in the source files)
What comes to mind is that the line terminations of the source files might be causing the error. Perhaps some '\r' are present there ? You should check that the line endings are unix-style (lines end with '\n')
Otherwise, try running cat File1 and cat File2 and check that the output is as expected. This should give you a hint as to why they are catted wrong

Related

Adding a separator between found results by sed

I have a text file like this for example:
test.txt:
Hello my name is test
Well my name will be test
Hello Hello test
Hello my name already is test
Now I want to get everything between every 'Hello' and 'test'. This works for me:
cat test.txt | sed --quiet '/Hello/,/test/p'
It gives the following output:
Hello my name is test
Hello Hello test
Hello my name already is test
Would it be possible to separate my findings like this:
Hello my name is test;
Hello Hello test;
Hello my name already is test;
The delimiter does not have to be ';' any other character will work just fine.
Your question is unclear, but, assuming you want lines that start with Hello and to add a semi colon at the end, you can try;
$ sed -n '/^Hello/{s/$/;/p}' input_file
Hello my name is test;
Hello Hello test;
Hello my name already is test;

Get first 5 lines of a file, using a file of program names as input (Unix)

Goal: using an input file with a list of file names, get the first 5 lines of each file and output to another file. Basically, I'm trying to find out what each program does by reading the header.
Shell: Ksh
Input: myfile.txt
tmp/file1.txt
tmp/file2.txt
Output:
tmp/file1.txt - "Creates web login screen"
tmp/file2.txt - "Updates user login"
I can use "head -5" but not sure how to get the input from the file. I'm assuming I could redirect (>> output.txt)the output for my output file.
Input file names use a relative path.
Update: I created a script below but I'm getting "syntax error: unexpected end of file". The script was created with VI.
#! /bin/sh
cat $HOME/jmarti20.list | while read line
do
#echo $line" >> jmarti20.txt
head -n 5 /los_prod/$line >> $HOME/jmarti20.txt
done
Right, you can append output with >> to a file.
head -n 5 file1.txt >> file_descriptions.txt
You can also use sed to print lines, from documentation at pinfo sed.
sed 5q file1.txt >> file_descriptions.txt
Personal preference is to put file description in line 3, and only print line 3 of files.
sed -n 3p file1.txt >> file_descriptions.txt
The reasoning for using line 3 has to do with the first line often containing a "shebang" like #!/bin/bash, and the 2nd line having localization strings, such as # -*- coding: UTF-8 -*-, to allow proper display of extra character glyphs and languages in terminals and text editors that support them.
Below is what I came up with and seems to work fairly well:
#! /bin/sh
cat $HOME/jmarti20.list | while read line
do
temp=$line
temp2=$(head -n 5 /los_prod/$line)
echo "$temp" "$temp2" >> jmarti20.txt
#echo "$line" >> jmarti20.txt
#head -n 5 /los_prod/$line >> $HOME/jmarti20.txt
done

cannot get proper output when concat strings with variables using bash

I have a simple script to read the content of a input file line by line with some extra strings added. Here is one example.
input file: input.txt
content of this input.txt
aaaaaa
bbbbbb
cccccc
dddddd
eeeeee
code to read the file
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "abc.def.hig.ewe.adg.hea.L_${line}.great"
done < "$1"
I'm not sure where exactly it is wrong; I cannot get correct output. It looks like when you add .great at the end of a variable, the output will mess up the sequence.
Transferring comments into an answer.
What output do you get? What output do you expect? I got five lines similar to:
abc.def.hig.ewe.adg.hea.L_aaaaaa.great
using Bash 3.2.57 and Bash 4.3 (on Mac OS X 10.11.5).
Is the data file from Windows or some other source that uses CRLF line endings? That will make things look like:
.greatf.hig.ewe.adg.hea.L_aaaaaa
instead of what I showed before. And, I note, this would have been readily explicable (or discountable) if you'd only showed the output you were getting.
Yes, you are right. The problem is the input file. It got corrupted when uploading from Windows to Unix.
Have you considered using something like awk? It is very good for these types of simple tasks.
$ cat input.txt
aaaa
bbbb
cccc
-
$ awk '{print "prefix_"$0"_suffix"}' input.txt
prefix_aaaa_suffix
prefix_bbbb_suffix
prefix_cccc_suffix

How to add string to empty lines of file in scripting?

Example : file1 has data like
abc
cab
def
xxy
zay
sri
ram
In this file 3rd,7th,9th lines are empty, how to fill this empty lines with Specific string?.
For example if i want to fill these lines with Hello
Output File should be like:
abc
cab
Hello
def
xxy
zay
Hello
sri
Hello
ram
sed 's/^$/Hello/' file1
will output what you want.
You can redirect that to the output file as below.
sed 's/^$/Hello/' file1 > file2
If you want to change the original file itself, you can use the -i option.
sed -i 's/^$/Hello/' file1

Redirection operator in UNIX

Suppose I have three files file1 file2 file3 having some content
Now when I do this on shell prompt cat file1 > file2 >file3
Content of file1 is copied to file3 and file2 becomes empty
Similarly when I do cat > file1 > file2 > file3
It ask for input and this input is stored in file3 and both file1 and file2 are empty
and also for cat > file1 > file2 < file3 contents of file3 is copied to file2 and file1 is empty.
Can someone please explain to me what is happening I am new to UNIX. Also any website where I can learn more about these redirection operators.
Thanks
Consider how the shell processes each part of the command as it parses it:
cat file1 > file2 >file3
cat file1: prepare a new process with the cat program image with argument file1. ( given 1 or more arguments, cat will read from each argument as a file and write to its output file descriptor)
> file2: change the new process' output file descriptor to write to file2 instead of the current output sink (initially the console for an interactive shell) - create `file2 if necessary.
> file3: change the new process' output file descriptor to write to file3 instead of the current output sink (was file2) - create file3 if necessary
End of command: Spawn the new process
So in the end, file2 is created, but unused. file3 gets the data.
cat > file1 > file2 > file3
cat: prepare a new process with the cat program/image with no arguments. (given no arguments, cat will read from its input file descriptor and write to its output file descriptor)
> file1: change the new process' output file descriptor to write to file1 instead of the current output sink (initially the console for an interactive shell) - create file1 if necessary.
> file2: change the new process' output file descriptor to write to file2 instead of the current output sink (was file1) - create file2 if necessary.
> file3: change the new process' output file descriptor to write to file3 instead of the current output sink - (was file2) create file3 if necessary
End of command: Spawn the new process
So in the end, file1 and file2 are created, but unused. file3 gets the data. cat waits for input on its input device (the console device as default for an interactive shell). Any input that cat receives will go to its output device (which ends up being file3 by the time the shell finished processing the command and invoked cat).
cat > file1 > file2 < file3
cat: prepare a new process with the cat program/image with no arguments. (given no arguments, cat will read from its input file descriptor and write to its output file descriptor)
> file1: change the new process' output file descriptor to write to file1 instead of the current output sink (initially the console for an interactive shell) - create file1 if necessary.
> file2: change the new process' output file descriptor to write to file2 instead of the current output sink (was file1) - create file2 if necessary.
< file3: change the new process' input file descriptor to read from file3 instead of the current input source (initially the console for an interactive shell)
End of command: Spawn the new process
So in the end, file1 is created, but unused. file2 gets the data. cat waits for input on its input device (which as set to file3 by the time the shell finished processing the command and invoked cat). Any input that cat receives will go to its output device (which ends up being file2 by the time the shell finished processing the command and invoked cat).
--
Note that in the first example, cat is the one who processes/opens file1. The shell simply passed the word file1 to the program as an argument. However, the shell opened/created file2 and file3. cat knew nothing about file3 and has no idea where the stuff it was writing to its standard output was going.
In the other 2 examples, the shell opened all the files. cat knew nothing about any files. cat had no idea where its standard input was coming from and where its standard output was going to.
Per #Sorpigal comment - the BASH manual has some good descriptions of what the different redirection operators do. Much of it is the same across different Unix shells to varying degrees, but consult your specific shell manual/manpage to confirm. Thanks #Sorpigal.
http://gnu.org/software/bash/manual/html_node/Redirections.html
You can redirect the standard input < standard output 1> or > error output 2> or both outputs &> but you can only redirect 1:1, you can't redirect one output into two different files.
What you are looking for is the tee utility.
If you don't want to lose original content, you should use redirect and append >> or << operators instead. You can read more here.

Resources