Im trying to take a file that has the following output and make it show the site and the Commands needed ran on that site. Meaning. Basically i want to take the SiteID in this case Site1 and add it to the front of the commands that need to be ran on that site.
Current File
Site1
'command;command2;command3'
Site2
'command;command2;command3'
Site3
'command;command2;command3'
Expected output is:
Site1 'command;command2;command3'
Site2 'command;command2;command3'
Site3 'command;command2;command3'
Try this sed
sed -i.bak 'N;s/\n//g' yourfile.txt
From man sed:
-i [SUFFIX], --in-place[=SUFFIX]
edit files in place (makes backup if extension supplied)
$ awk -F\' 'NF==1{site=$0;next} {print site, $0}' file
Site1 'command;command2;command3'
Site2 'command;command2;command3'
Site3 'command;command2;command3'
Use the paste command
paste - - <file
And it you want a space as a delimiter do
paste -d ' ' - - <file
Or if you must use awk:
awk '{printf "%s"(NR%2?" ":"\n"), $0}' file
Or a bit shorter awk command:
awk '{ORS=(NR%2?" ":"\n")}1' file
Related
I'm trying to add the filename of a text file into the first line of a the same text file. for example if the file name is called test1.txt, then the first line when you open the file should be test1.
below is what I've done so for, the only problem i have is that the word "$file" is being written to the file not the file name. any help is appreciated.
for file in *.txt; do
sed -i '1 i\$file' $file;
awk 'sub("$", "\r")' "$file" > "$file"1;
mv "$file"1 "$file";
done
Without concise, testable sample input and expected output it's an untested guess but it SOUNDS like all you need is:
awk -i inplace -v ORS='\r\n' 'FNR==1{print FILENAME}1' *
No shell loop or multiple commands required.
The above uses GNU awk for inplace editing and I'm assuming the sub() in your code was intended to add a \r at the end of every line.
I've just started learning more about sed and awk and put this into a file called insert.sed and sourced it and passed it a file name:
sed -i '1s/^./'$1'\'$'\n/g' $1
In trying it, it seems to work okay:
rent$ cat x.txt
<<< Who are you?
rent$ source insert.sed x.txt
rent$ cat x.txt
x.txt
<< Who are you?
It is cutting off the first character of the first line so I'd have to fix that otherwise it does add the file name to first line.
I'm sure there's better ways of doing it.
If you want test1 on first line, with gnu sed
sed -i '1{x;s/.*/fich=$(ps -p $PPID -o args=);fich=${fich##*\\} };echo ${fich%%.*}/e;G}' test1.txt
For example :let us consider my file contains 100 lines in which i need to delete 1st,2nd and 5th character from each line.
Try doing this
cut -c 3,4,6- file
See :
man cut
Sample Output
$ cat file
1abcdefgh
2abcdefgh
3abcdefgh
$ cut -c 3,4,6- file
bcefgh
bcefgh
bcefgh
you could give this a try:
awk 'BEGIN{FS=OFS=""}{$5=$1=$2=""}1' file
for example:
kent$ cat file
12345678foo
12345678foo
12345678foo
12345678foo
12345678foo
kent$ awk 'BEGIN{FS=OFS=""}{$5=$1=$2=""}1' file
34678foo
34678foo
34678foo
34678foo
34678foo
Thanks a lot for all your effort
I tried d first one and its working fine
$ cut -c 3,4,6- file
I have a file with lots of host names. Some have a url part after the host that I'd like to remove. In other words:
google.com
facebook.com
acme.com/news/frontpage
bbc.co.uk
abc.com/home/index
Should become
google.com
facebook.com
acme.com
bbc.co.uk
abc.com
One way:
sed 's|/.*||' file
Results:
google.com
facebook.com
acme.com
bbc.co.uk
abc.com
You may want to read more about using the slash as a delimiter. HTH.
Try doing this :
cut -d '/' -f1 file.txt
or
awk -F/ '{print $1}' file.txt
or
perl -F/ -lane 'print $F[0]' file.txt
awk -F/ '{print $1}' your_file
or
all the other solutions cannot change the file inplace.but in case of steve you need to add a -i flag for that sed solution.But still it will not work on solaris.
below perl solutiopn works on all the platform and replaces the file inplace
perl -pi -e 's/\/.*//g' your_file
I have a CSV. I want to edit the 35th field of the CSV and write the change back to the 35th field. This is what I am doing on bash:
awk -F "," '{print $35}' test.csv | sed -i 's/^0/+91/g'
so, I am pulling the 35th entry using awk and then replacing the "0" in the starting position in the string with "+91". This one works perfet and I get desired output on the console.
Now I want this new entry to get written in the file. I am thinking of sed's "in -place" replacement feature but this fetuare needs and input file. In above command, I cannot provide input file because my primary command is awk and sed is taking the input from awk.
Thanks.
You should choose one of the two tools. As for sed, it can be done as follows:
sed -ri 's/^(([^,]*,){34})0([^,]*)/\1+91\3/' test.csv
Not sure about awk, but #shellter's comment might help with that.
The in-place feature of sed is misnamed, as it does not edit the file in place. Instead, it creates a new file with the same name. eg:
$ echo foo > foo
$ ln -f foo bar
$ ls -i foo bar # These are the same file
797325 bar 797325 foo
$ echo new-text > foo # Changes bar
$ cat bar
new-text
$ printf '/new/s//newer\nw\nq\n' | ed foo # Edit foo "in-place"; changes bar
9
newer-text
11
$ cat bar
newer-text
$ ls -i foo bar # Still the same file
797325 bar 797325 foo
$ sed -i s/new/newer/ foo # Does not edit in-place; creates a new file
$ ls -i foo bar
797325 bar 792722 foo
Since sed is not actually editing the file in place, but writing a new file and then renaming it to the old file, you might as well do the same.
awk ... test.csv | sed ... > test.csv.1 && mv test.csv.1 test.csv
There is the misperception that using sed -i somehow avoids the creation of the temporary file. It does not. It just hides the fact from you. Sometimes abstraction is a good thing, but other times it is unnecessary obfuscation. In the case of sed -i, it is the latter. The shell is really good at file manipulation. Use it as intended. If you do need to edit a file in place, don't use the streaming version of ed; just use ed
So, it turned out there are numerous ways to do it. I got it working with sed as below:
sed -i 's/0\([0-9]\{10\}\)/\+91\1/g' test.csv
But this is little tricky as it will edit any entry which matches the criteria. however in my case, It is working fine.
Similar implementation of above logic in perl:
perl -p -i -e 's/\b0(\d{10})\b/\+91$1/g;' test.csv
Again, same caveat as mentioned above.
More precise way of doing it as shown by Lev Levitsky because it will operate specifically on the 35th field
sed -ri 's/^(([^,]*,){34})0([^,]*)/\1+91\3/g' test.csv
For more complex situations, I will have to consider using any of the csv modules of perl.
Thanks everyone for your time and input. I surely know more about sed/awk after reading your replies.
This might work for you:
sed -i 's/[^,]*/+91/35' test.csv
EDIT:
To replace the leading zero in the 35th field:
sed 'h;s/[^,]*/\n&/35;/\n0/!{x;b};s//+91/' test.csv
or more simply:
|sed 's/^\(\([^,]*,\)\{34\}\)0/\1+91/' test.csv
If you have moreutils installed, you can simply use the sponge tool:
awk -F "," '{print $35}' test.csv | sed -i 's/^0/+91/g' | sponge test.csv
sponge soaks up the input, closes the input pipe (stdin) and, only then, opens and writes to the test.csv file.
As of 2015, moreutils is available in package repositories of several major Linux distributions, such as Arch Linux, Debian and Ubuntu.
Another perl solution to edit the 35th field in-place:
perl -i -F, -lane '$F[34] =~ s/^0/+91/; print join ",",#F' test.csv
These command-line options are used:
-i edit the file in-place
-n loop around every line of the input file
-l removes newlines before processing, and adds them back in afterwards
-a autosplit mode – split input lines into the #F array. Defaults to splitting on whitespace.
-e execute the perl code
-F autosplit modifier, in this case splits on ,
#F is the array of words in each line, indexed starting with 0
$F[34] is the 35 element of the array
s/^0/+91/ does the substitution
I want to replace the date found at the end of the "datadir" line with the current date.
For e.g. my my.cnf file looks like this...
# head /etc/my.cnf
[mysqld]
#mount -t tmpfs -o size=102m tmpfs /mnt
#datadir=/mnt
read-only
datadir=/mysqlApr5
#datadir=/mysqlApr2
#datadir=/mysqlMar16
#datadir=/mysqlFeb25a
Most of the lines are commented. I need to find the datadir line that is not commented and then replace the /mysqlApr4 with /mysqlApr20
datadir=/mysqlApr20
If it is possible I will like to comment the older datadir path.
#datadir=/mysqlApr5
I can output the current date as:
date '+%b%d'
But I want to concat it with the word "/mysql" and replace or comment the current datadir line.
You can do it with sed and an in-place replacement:
sed -i "s|^datadir=.*$|datadir=/mysql`date '+%b%d'`|" /etc/my.cnf
If you want to comment out the old line and add a new one, you can use sed to do the commenting and just append a new line:
sed -i "s|^datadir=.*$|#\\0|" /etc/my.cnf
echo "datadir=/mysql`date '+%b%d'`" >> /etc/my.cnf
Perl one-liner which edits the file in-place:
perl -i -nle 'BEGIN { $date = `date +%b%d` }; if (/^datadir=/) { print qq{#$_\ndatadir=/mysql$date} } else {print}' my.cnf
awk -vd="$(date +%b%d)" '!/#/&&/datadir/{$0="#"$0"\ndatadir=/mysql"d}1' /etc/my.cnf>temp && mv temp file
All in one fell swoop:
sed -i '/^datadir.*/{s.^.#.;s.$.\ndatadir=/mysql'$(date "+%b%d")'.;q}' /etc/my.cnf
This will comment out the uncommented line. It adds the new line immediately below the old one instead of at the end of the file so it works similarly to the AWK and Perl versions shown.