Working with files in Expect - linux

I want to read a file contents, do some processing and write them to another file by using Expect scripting tool.
Let's assume that I have File_A contains the following data:
The IP address of this machine is: "0.0.0.0"
I want to read the contents of File_A, modify them and write them to File_B, which should be like the following:
The IP address of this machine is: "192.168.0.69"
Can anyone please help me with this?

you can use sed command to replace file content as below.Then use move command to make backup file as you want.
sed -i.bk 's/0.0.0.0/192.168.0.69/g' File_A.txt
mv File_A.txt.bk File_B.txt
Explanation:
sed = Stream EDitor
-i = in-place (i.e. save back to the original file)
The command string:
s = the substitute command
0.0.0.0 = a regular expression describing the word to replace (or just the word itself)
192.168.0.69 = the text to replace it with
g = global (i.e. replace all and not just the first occurred

Related

How to pass a variable along with file name in single line sftp put command

i want to sftp to other server and copy a file by changing file name dynamically using shell variable. i want to do this in a single line
Ex : i want to copy test.txt to other server with name my_test.txt
sftp user#hostname:/home/pavan/ <<< 'put test.txt $Dynamic_test.txt'
With this file is copied to destination server but copied with name as $Dynamic_test.txt and not my_test.txt
i also tried this, but no luck
sftp user#hostname:/home/pavan/ <<< 'put test.txt $Dynamic\\_test.txt'
Please let know. if some one has idea on this
To resolve the variables, you have to use double quotes (as everywhere else in shell):
sftp user#hostname:/home/pavan/ <<< "put test.txt $Dynamic_test.txt"

Deleting text in a file with "sed" isn't working as expected

I am currently working on a little script for the "nslookup"-command and in my testing I encountered a problem I don't understand. In my script a .txt file is automatically created and the user can input some text to it if he wishes to. He can also delete specific lines in the document. I tried writing it with "sed" but it doesn't seem to be working correctly.
Here the menu from the terminal output:
Domains:
1) new_domain
2) domain
3) Create new Domain
4) Delete a Domain
5) Quit
Input>
The first two numbers also representing the line of each text.
The code for deleting a domain is the following:
filename=domains.txt
old_filename=domains_backup.txt
read -p "Which domain-number shall be deleted?: " num_input
mv $filename $old_filename
sed "/$num_input/d" < $old_filename > $filename
rm $old_filename
But when executing that script and the user wants to delete line 2 (domain) the text-file remains the same and is not updated.
When I try the same only using the terminal everything works fine.
Is there something I'm missing?
To delete a line by its line number you will want to use $num_input d rather than /$num_input/d : the second one matches lines that contain $num_input.
As a side note, if you use GNU sed you could let it handle the backup :
sed -i.backup "$num_input d" domains.txt
This would create a copy of the untouched domains.txt as domains.txt.backup (or whatever suffix you specify after -i) and update the domains.txt file.

Using chef how to update a file after reading input from another file?

I am using linux commands to generate a file "a.txt" . Now I need to read the first word of file "a.txt" and update an existing file called "b.txt". I will search a word called "/fill " in b.txt and replace it with the word read from a.txt Below is the code
bash 'example' do
code <<-EOH
cat ex.txt >> a.txt
EOH
end
test = /#{'cat /a.txt'}/
file_names = ['/b.txt']
file_names.each do |file_name|
text = File.read(file_name)
new_contents = text.gsub(/fill, test)
puts new_contents
File.open(file_name, "w") {|file| file.puts new_contents }
With the help of linux command "cat ex.txt >> a.txt " I am putting the content of ex.txt to a.txt.
After this I want to read the file a.txt with test = /#{'cat /a.txt'}/. Example a.txt contains "azure" word
Now in b.txt I want to search for a word "/fill" and replace with content read in step 2 from b.txt file ie azure
The problem is instead of replacing /fill with azure, /fill is getting replaced with cat /a.txt.
Hope its clear now
Can you please help here
It is a bit hard to follow, what you actually want to achieve. Your code has a few issues. General advice:
put your ruby code inside a ruby_block resource so that is executed during Chef's convergence phase
Use Chef::Util::FileEdit, if you want to edit files that are not entirely managed by Chef (see this question for more inspiration)).
In case you really want to write the complete file using Chef, use a file resource and specify the content based on what you've read using File.read.
As said, ruby code outside of ruby_block is executed in the compile phase (which precedes the convergence phase). If you this is too early (because the source file isn't there yet, you can use a lazy block for lazy evaluation:
file "b.txt" do
content lazy { File.read .. }
end

Linux replace ^M$ with $ in csv

I have received a csv file from a ftp server which I am ingesting into a table.
While ingesting the file I am receiving the error "File was a truncated file"
The actual reason is the data in a file contains $ and ^M$ in end of the line.
e.g :
ACT_RUN_TM, PROG_RUN_TM, US_HE_DT*^M$*
"CONFIRMED","","3600"$
How can I remove these $ and ^M$ from end of the line using linux command.
The ultimately correct solution is to transfer the file from the FTP server in text mode rather than binary mode, which does the appropriate end-of-line conversion for you. Change your download scripts or FTP application configuration to enable text transfers to fix this in future.
Assuming this is a one-shot transfer and you have already downloaded the file and just want to fix it, you can use tr(1) to translate characters. So to remove all control-M characters from a file, you can pipe through tr -d '\r'. Or if you want to replace them with control-J instead – for example you would do this if the file came from a pre-OSX Mac system — do tr '\r' '\n'.
It's odd to see ^M as not-the-last character, but:
sed -e 's/^M*\$$//g' <badfile >goodfile
Or use "sed -i" to update in-place.
(Note that "^M" is entered on the command line by pressing CTRL-V CTRL_M).
Update: It's been established that the question is wrong as the "^M$" are not in the file but displayed with VI. He actually wants to change CRLF pairs to just LF.
sed -e 's/^M$//g' <badfile >goodfile

How can I replace a specific line by line number in a text file?

I have a 2GB text file on my linux box that I'm trying to import into my database.
The problem I'm having is that the script that is processing this rdf file is choking on one line:
mismatched tag at line 25462599, column 2, byte 1455502679:
<link r:resource="http://www.epuron.de/"/>
<link r:resource="http://www.oekoworld.com/"/>
</Topic>
=^
I want to replace the </Topic> with </Line>. I can't do a search/replace on all lines but I do have the line number so I'm hoping theres some easy way to just replace that one line with the new text.
Any ideas/suggestions?
sed -i yourfile.xml -e '25462599s!</Topic>!</Line>!'
sed -i '25462599 s|</Topic>|</Line>|' nameoffile.txt
The tool for editing text files in Unix, is called ed (as opposed to sed, which as the name implies is a stream editor).
ed was once intended as an interactive editor, but it can also easily scripted. The way ed works, is that all commands take an address parameter. The way to address a specific line is just the line number, and the way to change the addressed line(s) is the s command, which takes the same regexp that sed would. So, to change the 42nd line, you would write something like 42s/old/new/.
Here's the entire command:
FILENAME=/path/to/whereever
LINENUMBER=25462599
ed -- "${FILENAME}" <<-HERE
${LINENUMBER}s!</Topic>!</Line>!
w
q
HERE
The advantage of this is that ed is standardized, while the -i flag to sed is a proprietary GNU extension that is not available on a lot of systems.
Use "head" to get the first 25462598 lines and use "tail" to get the remaining lines (starting at 25462601). Though... for a 2GB file this will likely take a while.
Also are you sure the problem is just with that line and not somewhere previous (ie. the error looks like an XML parse error which might mean the actual problem is someplace else).
My shell script:
#!/bin/bash
awk -v line=$1 -v new_content="$2" '{
if (NR == line) {
print new_content;
} else {
print $0;
}
}' $3
Arguments:
first: line number you want change
second: text you want instead original line contents
third: file name
This script prints output to stdout then you need to redirect. Example:
./script.sh 5 "New fifth line text!" file.txt
You can improve it, for example, by taking care that all your arguments has expected values.

Resources