Delete everything after a certain character on each word using sed - linux

I want to create a script using sed to achieve the following:
This:
22/0,01 1/1,05 11/0,01 35/6,04 6/0,03 3/0,04
To:
22 1 11 35 6 3
I want to remove everything after "/" on each word.

Just remove everything from / up to a space:
$ sed 's#/[^ ]*##g' file
22 1 11 35 6 3
Note I am using # as delimiter to avoid having to escape the /.

if the "everything after the / consists only of known characters, then this is rather easy:
sed -e 's|/[0-9,]*||g'

Related

creating a blank line after some specific line using bash / linux

I need to add an additional blank line after the line 45 using sed
for example:
44 some text one
45 some text two
46 some text three
47 some text four
result:
44 some text one
45 some text two
46
47 some text three
48 some text four
I've tried to use
sed '45G' myfile.txt
but not seems to be working, it does prints content of the file on the screen but do not adds any space after the line 45
Using CentOS 7 minimal
You can do:
sed $'45 a \n' file.txt
$'' initiates C-style quoting, might be needed in some sed while using \n
45 a \n appends a newline (\n) after (a) the 45-th line
sed is for simple substitutions on individual lines, that is all. For anything else just use awk:
awk '{print} NR==45{print ""}' file
That will work with any awk on any UNIX box.

concatenating all files horizontally and only a specific column

In linux, is there a way to concatenate all the files in a directory that end with .out into one file? It would be even better if the final output file had them horizontally next to one another, rather than vertically. Even further, is it possible to only get the 6th column from each file (each column separated by a space).
I know I have been doing this in powershell. was wondering if linux can do this?
I know I can use
paste *.out > total.out
but how do I just paste the 6th column, which are separated by spaces?
Using bash and awk with temporary files to filter the sixth column of each *.out file.
#!/bin/bash
declare -a TEMPS
for name in *.out; do
TEMPS+=($(mktemp $name.XXXXXXXX))
awk '{ print $5 ;}' $name >${TEMPS[-1]}
done
paste -d ' ' "${TEMPS[#]}"
# Remove tmp files
rm "${TEMPS[#]}"
Output using the example files from #daniel
6 18 30
12 24 36
Save this script as a .sh file, then run it in your directory. This method uses sponge which you can install in Ubuntu with sudo apt-get install moreutils
saveColumn6.sh
# Make total.out a blank file
rm total.out
> total.out
# Go through every file ending in '.out'
for i in *.out
do
# cut out field 6, append it to total.out, and rewrite the file.
cut -d ' ' -f6 $i | paste -d' ' total.out - | sponge total.out
done
Here are the input files I used to test this.
in0.out
1 2 3 4 5 6
7 8 9 10 11 12
in1.out
13 14 15 16 17 18
19 20 21 22 23 24
in2.out
25 26 27 28 29 30
31 32 33 34 35 36
Here is the output file I received
total.out
6 18 30
12 24 36
Note that there is a leading space in this new database, I couldn't figure out how to get rid of that.
As Nightcrawler mentioned, Linux isn't the relevent component. You're looking for bash, the command-line shell used by many GNU/Linux based systems.

Replace a line with a number if part of it is matches using sed

I know this is a very simple question and been discussed many times, but I can't understand where I am doing wrong in my command.
I would like to replace the lines which starts with "It" as 99999. Each row starts with several blank spaces.
infile.txt
3
2
3
4
It is not a number = /home/kayan/data
3
5
It is not a number = /home/kayan/data
4
5
I used
sed -i 's/^I/99999/g' infile.txt
But it is not working.
Due to starting space, add it to pattern search
sed -i 's/^[[:blank:]]*I.*/99999/' infile.txt
using the change function
sed -i '/^[[:blank:]]*I/ c\
9999' infile.txt
keeping starting space
sed -i 's/^\([[:blank:]]*\)I.*/\199999/' infile.txt
No need of the g, there is only 1 change per line possible
give this a try:
sed -i 's/^\s*It.*/9999/'
What you are replacing there is just the ^I part, i.e. the first letter. Use ^I.* instead to match the whole remaining line and it also gets replaced.

remove trailing zero using awk

I have the following values in my file:
1.5000
0.006
9.0001
104.2500
17.0000
3.5000
I want to remove the trailing zero, the following awk will reove the trailing zeros
awk '{ if ($0 ~ /\./){ sub("0*$","",$0); sub ("\\.$","",$0);} print}' file
Output of above awk,
1.5
0.006
9.0001
104.25
17
3.5
But I want to add a single zero after the decimal point, I.e. All I want is a float number without trailing zero except values like, 2.0, 3.0
Excepted output
1.5
0.006
9.0001
104.25
17.0
3.5
Possible with sed:
sed 's/0\+$//;s/\.$/.0/'
If integers like 1200 can occur in the input, handle them separately:
sed '/\./{s/0\+$//;s/\.$/.0/;b};s/$/.0/'
Use of sed is probably simpler in this case:
Note:
The following uses sed with -E (alias of -r) to enable support for extended regular expressions, which makes the command more readable. It should work with GNU sed (Linux) and FreeBSD sed (OSX).
Uses a single substitution command (s/.../.../).
Should there be integers in the input, they are left untouched.
sed -E 's/^( *[0-9]+\.[0-9]([0-9]*[1-9])?)0+$/\1/' file
^ at the beginning and $ at the end ensure that the entire input line is matched
 * matches leading spaces, if any
[0-9]+\. matches all digits before the decimal point, plus the decimal point
[0-9] matches the first decimal place (a single digit) - this ensures that a number ending in .0 isn't stripped of its trailing 0
([0-9]*[1-9])? matches any additional digits until a nonzero digit is encountered, if any
0+ then captures trailing zeros through the end of the line
in the replacement string, \1 refers to the 1st capture group ((...)), which is everything except the trailing zeros - effectively removing them.
Note that due to seds default behavior of outputting all lines - whether modified or not - lines without matching numbers (numbers that didn't need modification) are simply passed through.
New version that handles better long numbers and text
cat file
1.5000
0.006
9.0001
104.2500
17.0000
3.5000
450.0005
test
my00000
awk '/^ *[0-9]+\.[0-9]+/{sub(/0+$/,"");sub(/\.$/,".0")}1' file
1.5
0.006
9.0001
104.25
17.0
3.5
450.0005
test
my00000
This replace all leading 0 with nothing. If you get . at final, replace it with .0
It also test if its start with 0 or more space, than number.
Use the below command for more accurate output,
Filename : sam
cat sam
45.0005
0.4440000
45.000000
66.66
44.000
.45000
45
awk '{if($0 ~ /^[0-9]*\.[0-9]+/) { sub(/0+$/,"") sub(/\.$/,".0") sub(/^\./,"0.");} else if($0 ~ /^[0-9]+$/) {sub(/$/,".0");}}1' sam
Output:
45.0005
0.444
45.0
66.66
44.0
0.45
45.0

How to remove words from a file in UNIX?

first file of information page
name/joe/salary1 50 10 2
name/don/miles2
20 4 3
name/sam/lb3 0 200 50
can some one please tell me how can I remove all the words in the above file, so my output will looks as follows
50 10 2
20 4 3
0 200 50
Use awk instead. The following code says to go through each field, check if its an integer. If it is, print them out. No need complicated regex.
$ awk '{for(i=1;i<=NF;i++) if($i+0==$i) {printf $i" "} print ""}' file
50 10 2
20 4 3
0 200 50
sed -e "s/[a-zA-Z/]/ /g" file
will do it, though I like codaddict's way more if you want to preserver number and whitespace. This way strips out all letters and the '/' symbol, replacing them all with space.
If you want to modify the file in place, pass the -i switch. This command will output what the file would look like.
Looks like you want to preserve only the digits and the space. If yes, you can do:
sed 's/[^0-9 ]//g' inputFile
EDIT: Change in requirements, if a digit is found with a letter, it should be treated as part of the word.
This Perl script does it:
perl -ne 's/(?:\d*[a-z\/]+\d*)*//g;print' input
If your file has this structure, I suggest first to filter out the first line, then remove all characters from beginning of line up to the first space:
sed -ni '2,$s/^[^ ]*//p' file
Remove everything on each line until first space character (also removes leading spaces):
sed 's/\S*\s*//' file

Resources