Substituting some characters in a text file (shell script).
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Substituting some characters in a text file (shell script).
Hi:
I have a text file from which I want to eliminate all newlines save in the case where two consecutive newlines are present. That is, one possible algorithm would be the following.
Code:
1. p=p+1 # advance character pointer
2. if char at position p = \n
if char position p+1 = \n
p=p+1
else
substitute char at p for ' '
3. goto step 1
If I want to implement it in the Bash script language, then
(a) I would begin by making use of a while sentence.
(b) I must treat p as a numeric variable.
(c) Is readline able to read char by char?
(d) And what would be a clause/instruction/sentence to write a file?
(e) Would it not be easier to have two files: one input file and one output file?
Could you give me some hints covering these points?
I consider myself able to write the script. If only I new how to write one character at a time, in the style of C's fputc, fput, putc and putchar. But by reading the bash manual the only builtin command that does output is printf. On the contrary, for input there is the read builtin command.
$ help read
read: read [-ers] [-u fd] [-t timeout] [-p prompt] [-a array] [-n nchars] [-d delim] [name ...]
...
If -n is supplied with a non-zero NCHARS argument, read returns after
NCHARS characters have been read.
$ help echo
echo: echo [-neE] [arg ...]
Output the ARGs. If -n is specified, the trailing newline is
suppressed. ...
Quote:
If only I new how to write one character at a time, in the style of C's fputc, fput, putc and putchar. But by reading the bash manual the only builtin command that does output is printf.
You can use printf or echo for output:
Code:
$ echo -n x ; echo -n y ; echo -n z ; echo
xyz
$ printf x ; printf y ; printf z ; printf '\n'
xyz
The thing is that I must read/modify a file or, else have the file to modify as input and do output on another file. But I think I now have enough material to begin thinking how I'll do it. Thanks a lot.
Thank you ntubski. Some day I'll get quite familiar with sed and awk. In the meantime, I'll keep your examples in order to study them in the future. I think that using the given file as input and letting the modified file be another file (output file) I can do it within a while loop and input/output redirection. For instance, for output, I'll use something like
semoi@darkstar:~/script/el_mio$ cat f1
#!/bin/bash
# 1. Read a char from infile
# 2. Output it to stdout
# 3. Goto step 1
while read -n 1 car1 # -n 1 reads only one char
do
echo -n $car1 # -n: do not output \n
done < infile
exit
semoi@darkstar:~/script/el_mio$ cat infile
To be or not to be. That is the question.
Whether 'tis nobler in the mind,
semoi@darkstar:~/script/el_mio$ ./f1
Tobeornottobe.Thatisthequestion.Whether'tisnoblerinthemind,semoi@darkstar:~/script/el_mio$
As you can see, either read or echo eats the spaces. Also, line terminators. Why?
Read a line from the standard input and split it into fields.
Reads a single line from the standard input, or from file descriptor FD
if the -u option is supplied. The line is split into fields as with word
splitting, and the first word is assigned to the first NAME, the second
word to the second NAME, and so on, with any leftover words assigned to
the last NAME. Only the characters found in $IFS are recognized as word
delimiters.
So to preserve spaces try this:
Code:
IFS="" read -n1 x && echo "[$x]"
i.e. set IFS to empty line.
To preserve newlines as well, add -d "":
Code:
while IFS="" read -n 1 -d "" car1 # -n 1 reads only one char
do
echo -n "$car1" # -n: do not output \n
done
Thank you ntubski. Some day I'll get quite familiar with sed and awk. In the meantime, I'll keep your examples in order to study them in the future. I think that using the given file as input and letting the modified file be another file (output file) I can do it within a while loop and input/output redirection. For instance, for output, I'll use something like
echo -n $var1 >>outfile.
That will work but will be gruesomely slow compared to an awk or sed solution. No matter for input files of a few hundred characters but for bigger files processed regularly ...
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.