Replace string in many js files - sed

I have many files(.js files), under a directory and subdirectories. I want to replace the lines which ends in ';', with the original line plus print.f("filename" with linenumber");. The actual filename and linenumber where it was found.
example - line ending with ';'
var x = 5;
should be replaced with
var x = 5;print.f("test.js with line number 16");
test.js and 16 are the filename and linenumber where var x = 5; was found respectively.
Edit
The test.js and 16 are samples, in the output it should be the filename and the linemunber

If you are flexible in using awk:
awk '{printf $0} /.*\;$/{printf " print.f(\"" FILENAME " with line number " NR "\");"} {printf "\n"}' filename
This will add the print.f statement whenever the lines ends with ;.
Unless you have GNU awk 4.1.0 or later, you will have to write the output of the command temporarily to a file and then move it back.
For GNU awk 4.1.0 and above, you can use -i option for inplace file editing.
gawk -i '{printf $0} /.*\;$/{printf " print.f(\"" FILENAME " with line number " NR "\");"} {printf "\n"}' filename
To find all .js files and run the above gawk command on them:
find . -type f -name "*.js" | xargs gawk -i '{printf $0} /.*\;$/{printf " print.f(\"" FILENAME " with line number " NR "\");"} {printf "\n"}'

Related

how to convert 23/1/17 to 23/01/2017 in a row of csv file with unix?

I am looking for how to convert all dates in a csv file row into this format ? example I want to convert 23/1/17 to 23/01/2017
I use unix
thank you
my file is like this :
23/1/17
17/08/18
1/1/2
5/6/03
18/05/2019
and I want this :
23/01/2017
17/08/2018
01/01/2002
05/06/2003
18/05/2019
I used date_samples.csv as my test data:
23/1/17,17/08/18,1/1/02,5/6/03,18/05/2019
cat date_samples.csv | tr "," "\n" | awk 'BEGIN{FS=OFS="/"}{print $2,$1,$3}' | \
while read CMD; do
date -d $CMD +%d/%m/%Y >> temp
done; cat temp | tr "\n" "," > converted_dates.csv ; rm temp; truncate -s-1 converted_dates.csv
Output:
23/01/2017,17/08/2018,01/01/2002,05/06/2003,18/05/2019
This portion of the code converts your "," to new lines and makes your input DD/MM/YY to MM/DD/YY, since the date command does not accept date inputs of DD/MM/YY. It then loops through re-arranged dates and convert them to DD/MM/YYYY format and temporarily stores them in temp.
cat date_samples.csv | tr "," "\n" | awk 'BEGIN{FS=OFS="/"}{print $2,$1,$3}' | \
while read CMD; do
date -d $CMD +%d/%m/%Y >> temp
done;
This line cat temp | tr "\n" "," > converted_dates.csv ; rm temp; truncate -s-1 converted_dates.csv converts the new line back to "," and puts the output to converted_dates.csv and deletes temp.
Using awk:
awk -F, '{ for (i=1;i<=NF;i++) { split($i,map,"/");if (length(map[3])==1) { map[3]="0"map[3] } "date -d \""map[2]"/"map[1]"/"map[3]"\" \"+%d/%m/%y\"" | getline dayte;close("date -d \""map[2]"/"map[1]"/"map[3]"\" \"+%d/%m/%y\"");$i=dayte }OFS="," }1' file
Explanation:
awk -F, '{
for (i=1;i<=NF;i++) {
split($i,map,"/"); # Loop through each comma separated field and split into the array map using "/" as the field seperator
if (length(map[3])==1) {
map[3]="0"map[3] # If the year is just one digit, pad out with prefix 0
}
"date -d \""map[2]"/"map[1]"/"map[3]"\" \"+%d/%m/%y\"" | getline dayte; # Run date command on day month and year and read result into variable dayte
close("date -d \""map[2]"/"map[1]"/"map[3]"\" \"+%d/%m/%y\""); # Close the date execution pipe
$i=dayte # Replace the field for the dayte variable
}
OFS="," # Set the output field seperator
}1' file

Set all whitespaces in a log to a single space

Hi I have a file with logs, some fields of this logs are separated by space and others by a tab or two spaces, how can I set all whitespaces to just a single space using powershell?
something similar to awk in linux bash, beacuse I have one field tha contains staces in his value like this: "type:Windows Resources"
awk '{print " $1 " " $2 " " $3 " " $5 " " $6 " " $7 " " $8 " " $9 " " $10}'
The below will replace only 2 or more spaces with single space.
((Get-Content logFile.txt) -replace '\s{2,}',' ') >> logFileTemp.txt;
Copy-Item logFileTemp.txt logFile.txt -Force
$test = " Testing removal of spaces"
$SpacesConverted = $test -replace "[ ]{1,1000}"," "
$SpacesConverted
Output:
Testing removal of spaces
What I'm doing is replacing spaces, looking for any space between 1 and a 1000 and converting that to a single space. If you have more than 1000 spaces in any given part of the log just increase that number.
If you want to run this on a file...
$File = "c:\file123.txt"
gc $File -replace "[ ]{1,1000}"," " | sc $File
Something like this, replace 1 or more whitespaces:
echo "hi hi`t`thi" > file1.txt
cat file1.txt
hi hi hi
(cat file1.txt) -replace '\s+',' ' | set-content file2.txt
cat file2.txt
hi hi hi

how to put | between content lines of a text file?

I have a file containing:
L1
L2
L3
.
.
.
L512
I want to change its content to :
L1 | L2 | L3 | ... | L512
It seems so easy , but its now 1 hour Im sitting and trying to make it, I tried to do it by sed, but didn't get what I want. It seems that sed just inserts empty lines between the content, any suggestion please?
With sed this requires to read the whole input into a buffer and afterwards replace all newlines by |, like this:
sed ':a;N;$!ba;s/\n/ | /g' input.txt
Part 1 - buffering input
:a defines a label called 'a'
N gets the next line from input and appends it to the pattern buffer
$!ba jumps to a unless the end of input is reached
Part 2 - replacing newlines by |
s/\n/|/ execute the substitute command on the pattern buffern
As you can see, this is very inefficient since it requires to:
read the complete input into memory
operate three times on the input: 1. reading, 2. substituting, 3. printing
Therefore I would suggest to use awk which can do it in one loop:
awk 'NR==1{printf $0;next}{printf " | "$0}END{print ""}' input.txt
Here is one sed
sed ':a;N;s/\n/ | /g;ta' file
L1 | L2 | L3 | ... | L512
And one awk
awk '{printf("%s%s",sep,$0);sep=" | "} END {print ""}' file
L1 | L2 | L3 | ... | L512
perl -pe 's/\n/ |/g unless(eof)' file
if space between | is not mandatory
tr "\n" '|' YourFile
Several options, including those mentioned here:
paste -sd'|' file
sed ':a;N;s/\n/ | /g;ta' file
sed ':a;N;$!ba;s/\n/ | /g' file
perl -0pe 's/\n/ | /g;s/ \| $/\n/' file
perl -0nE 'say join " | ", split /\n/' file
perl -E 'chomp(#x=<>); say join " | ", #x' file
mapfile -t ary < file; (IFS="|"; echo "${ary[*]}")
awk '{printf("%s%s",sep,$0);sep=" | "} END {print ""}' file

Substituting path

I want to replace path in
(setq myFile "/some/path")
in a file. I tried to do it with sed:
find ./_build/html -type f -name '*.html' | while read myFile; do
MyFile=`readlink -f "$myFile"`
sed -i "s/setq myFile [)]*/setq myFile \"$MyFile\"/" sphinx_nowrap.el
# and then some actions on file
done
and with perl:
find ./_build/html -type f -name '*.html' | while read myFile; do
MyFile=`readlink -f "$myFile"`
perl -ne "s/setq myFile .+/setq myFile \"$MyFile\")/" sphinx_nowrap.el
# and then some actions on file
done
but both give errors.
I've read this and this and also this -- but can't make it work.
Edit:
Here's a perl error:
Having no space between pattern and following word is deprecated at -e line 1.
Bareword found where operator expected at -e line 1, near "s/setq myFile .+/setq myFile "/home"
String found where operator expected at -e line 1, at end of line
(Missing semicolon on previous line?)
syntax error at -e line 1, near "s/setq myFile .+/setq myFile "/home"
Can't find string terminator '"' anywhere before EOF at -e line 1.
and here's sed error:
sed: -e expression #1, char 34: unknown option to `s'
Edit 2:
So the solution is to change the delimeter char. And also sed expression should be changed:
sed -i "s!setq myFile .*!setq myFile \"$MyFile\")!" sphinx_nowrap.el
Looks like perl (and sed) recognizes the slash in the file path as the regex delimiter. You can use a different delimiter:
find ./_build/html -type f -name '*.html' | while read myFile; do
MyFile=`readlink -f "$myFile"`
perl -ne "s!setq myFile .+!setq myFile \"$MyFile\")!" sphinx_nowrap.el
# and then some actions on file
done
or for sed:
find ./_build/html -type f -name '*.html' | while read myFile; do
MyFile=`readlink -f "$myFile"`
sed -i "s!setq myFile [)]*!setq myFile \"$MyFile\"!" sphinx_nowrap.el
# and then some actions on file
done
Lets assume your $MyPath hold /foo/bar/baz. Then the Perl code reads as:
perl -ne "s/setq myFile .+/setq myFile \"/foo/bar/baz\")/" sphinx_nowrap.el
Your Regex is terminated with the third / character. To work around this, we can use another delimiter like s{}{}:
perl -ine "s{setq myFile .+}{setq myFile \"/foo/bar/baz\")}; print" sphinx_nowrap.el
I also added the -i Option (inplace editing) and a print statement so that something actually gets print out.
But probably it would be more elegant to pass the value aof $MyPath as a command line argument:
perl -ne 's{setq myFile .+}{setq myFile "$ARGV[0]")}; print' $MyPath <sphinx_nowrap.el >sphinx_nowrap.el

How to strip characters within a filename?

I am having trouble on stripping characters within a filename.
For example:
1326847080_MUNDO-Cinco-Cosas-Que-Aprendimos-Del-Debate-De-Los-Republicanos-1.xml
1326836220_PLANETACNN-Una-Granja-De-Mariposas-Ayuda-A-Reducir-La-Tala-De-Bosques-En-Tanzania-3.xml
This is the output I want:
1326847080_MUNDO-1.xml
1326836220_PLANETACNN-3.xml
for i in *.xml
do
j=$(echo $i | sed -e s/-.*-/-/)
echo mv $i $j
done
or in one line:
for i in *.xml; do echo mv $i $(echo $i | sed -e s/-.*-/-/); done
remove echo to actually perform the mv command.
Or, without sed, using bash builtin pattern replacement:
for i in *.xml; do echo mv $i ${i//-*-/-}; done
rename to the rescue, with Perl regular expressions. This command will show which moves will be made; just remove -n to actually rename the files:
$ rename -n 's/([^-]+)-.*-([^-]+)/$1-$2/' *.xml
1326836220_PLANETACNN-Una-Granja-De-Mariposas-Ayuda-A-Reducir-La-Tala-De-Bosques-En-Tanzania-3.xml renamed as 1326836220_PLANETACNN-3.xml
1326847080_MUNDO-Cinco-Cosas-Que-Aprendimos-Del-Debate-De-Los-Republicanos-1.xml renamed as 1326847080_MUNDO-1.xml
The regular expression explained:
Save the part up to (but excluding) the first dash as match 1.
Save the part after the last dash as match 2.
Replace the part from the start of match 1 to the end of match 2 with match 1, a dash, and match 2.
sorry for the late reply , but i saw it today :( .
I think you are looking for the following
input file ::
cat > abc
1326847080_MUNDO-Cinco-Cosas-Que-Aprendimos-Del-Debate-De-Los-Republicanos-1.xml
1326836220_PLANETACNN-Una-Granja-De-Mariposas-Ayuda-A-Reducir-La-Tala-De-Bosques-En-Tanzania-3.xml
code : (its a bit too basic , even for my liking)
while read line
do
echo $line ;
fname=`echo $line | cut -d"-" -f1`;
lfield=`echo $line | sed -n 's/\-/ /gp' | wc -w`;
lname=`echo $line | cut -d"-" -f${lfield}`;
new_name="${fname}-${lname}";
echo "new name is :: $new_name";
done < abc ;
output ::
1326847080_MUNDO-Cinco-Cosas-Que-Aprendimos-Del-Debate-De-Los-Republicanos-1.xml
new name is :: 1326847080_MUNDO-1.xml
1326836220_PLANETACNN-Una-Granja-De-Mariposas-Ayuda-A-Reducir-La-Tala-De-Bosques-En-Tanzania-3.xml
new name is :: 1326836220_PLANETACNN-3.xml