Prepend number to the beginning of some lines in bash - linux

I have a file with some numbers
for example
$cat file
347678126
345258126
4378126
349878126
346123126
9678130
344838126
5678126
And i need add the number 34 to a line if the line does not begin with 34, and if the line begins in 34 not add anything
Output:
$cat file
347678126
345258126
344378126
349878126
346123126
349678130
344838126
345678126
I am intenting with a awk:
cat file | awk '{print 34$1}' > file2
But it add 34 to all lines.
Could you help me?

sed is handy to edit file in-place
sed -i '/^34/!s/^/34/' file

You're almost there, you just have to filter out the lines that do start with 34:
awk '!/^34/{printf 34}1' file

Related

exclude data from latest / to the end of row

I have the input file (myfile) as:
/data/152.18224487:2,S/proforma invoice.doc
/data/152.916612:2,/proforma invoice.doc
/data/152.48152834/Bank T.T Copy 12 d3d.doc
/data/155071755/Bank T.T Copy.doc
/data/1521/Quotation Request.doc
/data/15.462/Quotation Request 2ds.doc
/data/15.22649962_test4/Quotation Request 33 zz (.doc
/data/15.226462_test6/Quotation Request.doc
and I need to exclude all data after latest "/" to the end of the row to have this output:
/data/152.18224487:2,S
/data/152.916612:2,
/data/152.48152834
/data/155071755
/data/1521
/data/15.462
/data/15.22649962_test4
/data/15.226462_test6
How can I do this from command line linux ?
This is a follow-up question related to extract last section of data from file using linux command
Could you please try following.
awk 'match($0,/\/.*\//){print substr($0,RSTART,RLENGTH-1)}' Input_file
Above will look from / to till last occurrence of / in case your Input_file can start other than / then try following.
awk 'match($0,/.*\//){print substr($0,RSTART,RLENGTH-1)}' Input_file
This one is combined with your previous question ,
ie. data:
>> Vi 'x' found in file /data/152.916612:2,/proforma invoice.doc
>> Vi 'x' found in file /data/152.48152834/Bank T.T Copy 12 d3d.doc
>> Vi 'x' found in file /data/155071755/Bank T.T Copy.doc
...
wwk:
$ awk '
(s=match($0,/found in file /)+RLENGTH) && (match(substr($0,s),/.*\//)) {
print substr($0,s,RLENGTH-1)
}' file
Output:
/data/152.18224487:2,S
/data/152.916612:2,
/data/152.48152834
...
Try
sed 's:/[^/]*$::' < inputfile > outputfile
You stated in a comment elsewhere that you also need only the rest after the last slash, so here we go:
sed 's:^.*/::' < inputfile > outputfile
awk -F/ '{print "/"$1$2"/"$3}' file
/data/152.18224487:2,S
/data/152.916612:2,
/data/152.48152834
/data/155071755
/data/1521
/data/15.462
/data/15.22649962_test4
/data/15.226462_test6

Replacing a substring in certain lines of file A by string in file B

I have 2 files at the moment, file A and file B. Certain lines in file A contain a substring of some line in file B. I would like to replace these substrings with the corresponding string in file B.
Example of file A:
#Name_1
foobar
info_for_foobar
evenmoreinfo_for_foobar
#Name_2
foobar2
info_for_foobar2
evenmoreinfo_for_foobar2
Example of file B:
#Name_1_Date_Place
#Name_2_Date_Place
The desired output I would like:
#Name_1_Date_Place
foobar
info_for_foobar
evenmoreinfo_for_foobar
#Name_2_Date_Place
foobar2
info_for_foobar2
evenmoreinfo_for_foobar2
What I have so far:
I was able to get the order of the names in File B corresponding to those in File A. So I was thinking to use a while loop here which goes through every line of file B, and then finds and replaces the corresponding substring in file A with that line, however I'm not sure how to put this into a bash script.
The code I have so far is, but which is not giving a desired output:
grep '#' fileA.txt > fileAname.txt
while read line
do
replace="$(grep '$line' fileB.txt)"
sed -i 's/'"$line"'/'"$replace"'/g' fileA.txt
done < fileAname.txt
Anybody has an idea?
Thanks in advance!
You can do it with this script:
awk 'NR==FNR {str[i]=$0;i++;next;} $1~"^#" {for (i in str) {if(match(str[i],$1)){print str[i];next;}}} {print $0}' B.txt A.txt
This awk should work for you:
awk 'FNR==NR{a[$0]; next} {for (i in a) if (index(i, $0)) $0=i} 1' fileB fileA
#Name_1_Date_Place
foobar
info_for_foobar
evenmoreinfo_for_foobar
#Name_2_Date_Place
foobar2
info_for_foobar2
evenmoreinfo_for_foobar2

print specific line if it is matches with the line after it

I have a log file containing the following info:
<msisdn>37495989804</msisdn>
<address>10.14.14.26</address>
<msisdn>37495371855</msisdn>
<address>10.14.0.172</address>
<msisdn>37495989832</msisdn>
<address>10.14.14.29</address>
<msisdn>37495479810</msisdn>
<address>10.14.1.11</address>
<msisdn>37495429157</msisdn>
<address>10.14.0.213</address>
<msisdn>37495275824</msisdn>
<msisdn>37495739176</msisdn>
<address>10.14.2.86</address>
<msisdn>37495479840</msisdn>
<address>10.14.1.12</address>
<msisdn>37495706059</msisdn>
<msisdn>37495619889</msisdn>
<address>10.14.1.198</address>
<msisdn>37495574341</msisdn>
<address>10.14.1.148</address>
<msisdn>37495391624</msisdn>
<address>10.14.0.188</address>
<msisdn>37495989796</msisdn>
<address>10.14.14.24</address>
<msisdn>37495835940</msisdn>
<address>10.14.2.164</address>
<msisdn>37495743249</msisdn>
<address>10.14.2.94</address>
<msisdn>37495674117</msisdn>
<address>10.14.1.236</address>
<msisdn>37495754536</msisdn>
<address>10.14.2.120</address>
<msisdn>37495576434</msisdn>
<msisdn>37495823889</msisdn>
<address>10.14.2.159</address>
There are some lines where the 'msisdn' line is not followed by an 'address' line, like this:
<msisdn>37495576434</msisdn>
<msisdn>37495823889</msisdn>
I would like to write a script which will output only the lines ('msisdn' lines), that aren't followed by 'address'. Expected output:
<msisdn>37495275824</msisdn>
<msisdn>37495706059</msisdn>
<msisdn>37495576434</msisdn>
If it will be smth with awk/sed, it will be perfect.
Thanks.
One way with awk:
awk '/address/{p=0}p{print a;p=0}/msisdn/{a=$0;p=1}' log
you can use pcregrep to match next line is not adddress and use awk show it
pcregrep -M '(.*</msisdn>)\n.*<msi' | awk 'NR % 2 == 1'
This might work for you (GNU sed):
sed -r '$!N;/(<msisdn>).*\n.*\1/P;D' file
This reads 2 lines into the pattern space and trys to match the pattern <msisdn> in both the 2 lines. If the pattern matchs it prints out the first line. The first line is then deleted and the process begins again, however since the pattern space contains the second line (now the first), the automatic reading of a line is forgone and process begins as of $!N.
Perl has its own way to do this:
perl -lne 'if($prev && $_!~/\./){print $prev}unless(/\./){$prev=$_}else{undef $prev}' your_file
Tested Below:
> perl -lne 'if($prev && $_!~/\./){print $prev}unless(/\./){$prev=$_}else{undef $prev}' temp
<msisdn>37495275824</msisdn>
<msisdn>37495706059</msisdn>
<msisdn>37495576434</msisdn>
>

How to add two lines of number from a file in bash shell scripting?

I was trying to add the numbers from a file in shell and I am kinda stuck. I am new to bash and I dont know how to do it.
My file example is like this.
cat temp
23 49
35 50
what I want to do is to add 23 and 35 and to add 49 and 50. Any ideas will be helpful.
Thanks.
Using awk:
awk '{f1+=$1;f2+=$2} END{print f1" "f2}' temp
what if i want to save f1 and f2 to another file call temp1, how can i
do that?
Redirect the standard output to file temp1.
awk '{f1+=$1;f2+=$2} END{print f1" "f2}' temp > temp1
You can use bc to eval any numeric expression:
echo "32 + 33" | bc
Or for the whole file:
sed 's/ /+/' < temp|bc

Extract K-th Line from Chunks Using Sed/AWK/Perl

I have some data that looks like this. It comes in chunk of four lines. Each chunk starts with a # character.
#SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
AAAAAAAAAAAAAAAAAAAAAAAAAAA
+SRR037212.1 FC30L5TAA_102708:7:1:741:1355 length=27
::::::::::::::::::::::::;;8
#SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
TATAACCAGAAAGTTACAAGTAAACAC
+SRR037212.2 FC30L5TAA_102708:7:1:1045:1765 length=27
88888888888888888888888888
What I want to do is to extract last line of each chunk. Yielding:
::::::::::::::::::::::::;;8
888888888888888888888888888
Note that the last line of the chunk may contain any standard ASCII character
including #.
Is there an effective one-liner to do it?
The following sed command will print the 3rd line after the pattern:
sed -n '/^#/{n;n;n;p}' file.txt
If there are no blank lines:
perl -ne 'print if $. % 4 == 0' file
$ awk 'BEGIN{RS="#";FS="\n"}{print $4 } ' file
::::::::::::::::::::::::;;8
88888888888888888888888888
If you always have those 4 lines in a chunk, some other ways
$ ruby -ne 'print if $.%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888
$ awk 'NR%4==0' file
::::::::::::::::::::::::;;8
88888888888888888888888888
It also seems like your line is always after the line that start with "+", so
$ awk '/^\+/{getline;print}' file
::::::::::::::::::::::::;;8
88888888888888888888888888
$ ruby -ne 'gets && print if /^\+/' file
::::::::::::::::::::::::;;8
88888888888888888888888888
This prints the lines before lines that starts with #, and also the last line. It can work with non uniform sized chunks, but assumes that only a chunk leading line starts with #.
sed -ne '1d;$p;/^#/!{x;d};/^#/{x;p}' file
Some explanation is in order:
First you don't need the first line so delete it 1d
Next you always need the last line, so print it $p
If you don't have a match swap it into the hold buffer and delete it x;d
If you do have match swap it out of the hold buffer, and print it x;p
This works similarly to dogbane's answer
awk '/^#/ {mark = NR} NR == mark + 3 {print}' inputfile
And, like that answer, will work regardless of the number of lines in each chunk (as long as there are at least 4).
The direct analog to that answer, however, would be:
awk '/^#/ {next; next; next; print}' inputfile
this can be done using grep easily
grep -A 1 '^#' ./infile
This might work for you (GNU sed):
sed '/^#/,+2d' file

Resources