Pipe between two text files in BASH - bash

I'm new to all this(one day old bash coder) so as much as stupid this question might sound, please take your time and respond accordingly :)
I created a script in BASH that should do some things to a given input(which is a text file). I'm having some hard time trying to figure out how to use pipeline to run the script(which is called cleanLines, for the sake of the question) on a text file (named test.txt) so that it'll "clean his lines".
I added the below line of code to the top of my script file(cleanLines):
PATH=${PATH[*]}:.
Now what?
./test.txt | ./cleanLines.txt
Doesn't seem to work.
I should note that the files are in the same directory, if that worths anything to you.
EDIT: Oh and cleanLines is also a text file(.txt).
And it gives me the error:
-bash: ./cleanLines.txt: Permission denied

A pipe | redirects the output of a command, but test.txt is not a command. You can read more about redirection here or here. To redirect input from a file you would do this instead:
cleanLines < test.txt
This assumes that your script is executable and expecting input from standard input.

Related

Cygwin on Windows 7 (64bit): No such file or directory - but 'which' does give me the correct path

A formely working bash script no longer works after switching computers. I get the following error:
No such file or directory.
Before going on, please excuse any mistakes you may find since english is not my native language.
The script was used in cygwin under Windows XP. I now had to switch to cygwin64 under Windwos 7 (64bit).
The script is used as a checkhandler for the program SMSTools3 to split a file with a specific format into multiple smaller ones, which the program then uses to send SMS to multiple recipients. The script was copied directly from the page of SMSTools3 and uses the package formail.
After looking up the error the most likely problem was that the environmantle path was not set up to look in the right path (/usr/bin). I therefore added it to the path but to no avail.
I then deleted other entries in the enviromental path of windows which contained spaces because that could have been another explanation, but again to no avail.
Following is a minimal example of the code which produces the error.
#!/bin/bash
# Sample script to allow multiple recipients in one message file.
# Define this script as a checkhandler.
echo $PATH
which formail
outgoing="/var/spool/sms/outgoing"
recipients=`formail -zx "To:" < "$1"`
I added the lines the lines echo $Path and which formail to show if the script can find the correct file. Both results look fine, the second command gives me the right output '/usr/bin/formail'
But the line recipients=... throws me the error:
No such file or directory.
I do not have much experience with bash scripting, or cygwin in general. So if someone on this wonderful board could help me solve this problem, I would be really grateful. Thank you all for your help.
EDIT:
First of all thank you all for your comments.
Secondly, I would like to apologize for the late reply. The computer in question is also used for other purposes and my problem is part of a background routine, so I have to wait for "free time" on the pc to test things.
For the things #shellter pruposed: The ls command returned an error: '': No such file or directory.
The which -a formail as well as the echo $(which -a formail) commands that #DougHenderson pruposed returned the 'right' path of /usr/bin/formail. echo \$1 = $1 before the recipent line returned the path to the checkhandler file (/usr/local/bin/smsd_checkhandler.sh), the same command after the recipent line seems to show a empty string ($1 = ). Also, the pruposed change to the recipent line did not change the error.
For the dos2unix conversion that #DennisWilliamson pruposed, I opened the file in notepad++ to use their build in converion, but it showed me that the file is in unix format with Unix style line endings.

What is mean that `grep -m 1 ` command in UNIX

I googled this command but there was not.
grep -m 1 "\[{" xxx.txt > xxx.txt
However I typed this command, error didn't occured.
Actually, there was not also result of this command.
Please anyone explain me this command's working?
This command reads from and writes to the same file, but not in a left-to-right fashion. In fact > xxx.txt runs first, emptying the file before the grep command starts reading it. Therefore there is no output. You can fix this by storing the result in a temporary file and then renaming that file to the original name.
PS: Some commands, like sed, have an output file option which works around this issue by not relying on shell redirects.

.sh output to .txt file - what am I doing wrong?

I am running Windows 10 and am trying to save the error output of a test.sh file to a text file.
So I created the test.sh file and wrote an unkown command in it (i.e. "blablubb").
After that I open the terminal (cmd.exe), switch to the directory and type test.sh 2>> log.txt.
Another window opens with "/usr/bin/bash --login -i \test.sh" in the title bar, shows me "bash: blablubb: command not found" and then closes immediately.
I want to save that output because the bash-window just opens for a split second. Every google search brings me to websites talking about redirecting the output and that Stream2 ist STDERR and therefore I should use test.sh 2>> log.txt or something smiliar that takes care of the STDERR stream.
If I try the same with a test.sh file and the content:
#!/bin/bash
echo hi there
I get the output in the briefly open bash-window:
bash: #!/bin/bash: No such file or directory
hi there
But the log.txt file is empty.
If I only have echo hi therein the test.sh file I get bash: echo: command not found in the bash-window.
The log.txt also empty.
If I type the following directly in the terminal, the output is written in the log.txt:
echo hi > log.txt 2>&1
If I type directly in the terminal:
echdo hi > log.txt 2>&1
I get 'Der Befehl "echdo" ist entweder falsch geschrieben oder konnte nicht gefunden werden.' in the log.txt file.
So I guess the redirecting of the output works fine until I use test.sh.
I know that .sh files are something from the unix world and that the problem might lie there but I don't know why I can not redirect the output briefly shown in the bash-console to a text file.
The 2>> redirection syntax only works if the command line containing that syntax is interpreted by bash. So it won't work from the Windows command prompt, even if the program you are running happens to be written in bash. By the time bash is running, it's too late; it gets the arguments as they were interpreted by CMD or whatever your Windows command interpreter is. (In this case, I'm guessing that means the shell script will find it has a command line argument [$1] with the value "2".)
If you open up a bash window (or just type bash in the command one) and then type the test.sh 2>>log.txt command line in that shell, it will put the error message in the file as you expect.
I think you could also do it in one step by typing bash -c "test.sh 2>>log.txt" at the Windows command prompt, but I'm not sure; Windows quoting is different than *nix quoting, and that may wind up passing literal quotation marks to bash, which won't work.
Note that CMD does have the 2>> syntax as well, and if you try to run a nonexistent windows command with 2>>errlog.txt, the "is not recognized" error message goes to the file. I think the problem comes from the fact that CMD and bash disagree on what "standard error" means, so redirecting the error output from Windows doesn't catch the error output by bash. But that's just speculation; I don't have a bash-on-Windows setup handy to test.
It would help to know if you are running Windows Subsystem for Linux (Beta). Or if you are doing something else. I'm assuming this is what you are doing on windows 10.
If this is the case are you using bash to run the script?
Are you using win-bash?
If it is win-bash I'm not very familiar and would recommend Windows Subsystem for Linux (Beta) for reasons like this. win-bash, while cool, might not be compatible with redirection operators like 2>>.
You have stdout and stderr, by default (if you don't specify) the >> (or append) will only append standard output into the txt file.
If you use 2 it will append the standard error into the txt file. Example: test.sh 2>> log.txt
This could be better described at this site.
To get exactly the command for append both stdout and stderr, go to this page.
Please tell me if this doesn't answer your question. Also, it could be more valuable to attempt a search for this answer first and explain why your search found nothing or give more extensive clarification as to what the problem is. I love answering questions and helping, but creating a new forum page for what might be an easy answer may be ineffective. I've had a bunch of fun with your question. I hope that I've helped.
That's makes a lot of sense. Thanks Mark!
Taking what mark says into account I would get Windows Subsystem for Linux (Beta). There are instructions here. Then run your script from there.

Writing a Unix shell script which will edit a certain line of a .in file

I'd like to run a program several times with slightly different inputs. The input file is a long .in file, and I'd only want to edit a single number in a specific line of that file. So ideally I'd like to write a Unix script that repeats this process several times:
Edits a line in a .in file
Runs a program which uses that file as input
Renames the output .nc file from the program and saves it
I'm completely new to this sort of scripting, and while I'm pretty sure I can figure out how to do steps 2 and 3 of this process, I'm not sure how to do the second step. Is it possible to use a script to automate the editing of a .in file, and how would I do that?
Here's an example that should get you started:
$ echo cat says meow >say.txt
$ sed -i s/meow/meowwwwwww/ say.txt
$ cat say.txt
cat says meowwwwwww
Let me know if you need more help.

key logging in unix

I am a newbie to unix scripting, I want to do following and I have little clue how to proceed.
I want to log the input and output of certain set of commands, given on the terminal, to a trace file. I should be able to switch it on and off.
E.g.
switch trace on
user:echo Hello World
user:Hello World
switch trace off
Then the trace log file, e.g. trace.log, it's content should be
echo Hello World
Hello World
One thing that I can think to do is to use set -x, redirecting its output to some file, but couldn't find a way to do that. I did man set, or man -x but I found no entry. Maybe I am being too naive, but some guidance will be very helpful.
I am using bash shell.
See script(1), "make typescript of terminal session". To start a new transcript in file xyz: script xyz. To add on to an existing transcript in file xyz: script -a xyz.
There will be a few overhead lines, like Script started on ... and Script done on ... which you could use awk or sed to filter out on printout. The -t switch allows a realtime playback.
I think there might have been a recent question regarding how to display a transcript in less, and although I can't find it, this question and this one address some of the same issues of viewing a file that contains control characters. (Captured transcripts often contain ANSI control sequences and usually contain Returns as well as Linefeeds.)
Update 1 A Perl program script-declutter is available to remove special characters from script logs.
The program is about 45 lines of code found near the middle of the link. Save those lines of code in a file called script-declutter, in a subdirectory that's on your PATH (for example, $HOME/bin if that's on your search path, else (eg) /usr/local/bin) and make the file executable. After that, a command like
script-declutter typescript > out
will remove most special characters from file typescript,
while directing the result to file out.

Resources