use case:
adding a pre-action is readable through xcode,
but gibberish in xml
question:
is there a way to make scriptText human readable on xml?
example:
code from Pre-actions
function decode() { echo "${*}" | base64 --decode; }
KEY="FLAVOR"
FILE=${SRCROOT}/Flutter/DartDefineFlavor.xcconfig
test -f $FILE || touch $FILE
IFS=',' read -r -a ENCODED_ITEMS <<< "$DART_DEFINES"
for ENCODED_ITEM in ${ENCODED_ITEMS[#]}
do
DECODED_ITEM=$(decode "$ENCODED_ITEM")
IFS=' ' read -r K V <<< ${DECODED_ITEM//[=]/ };
if [ $K = $KEY ]; then
echo "DART_DEFINE_BUNDLE_SUFFIX=.$V" >> $FILE
break
fi
done
expectation:
<ActionContent
title = "Load Dart Define"
scriptText =
"
function decode() { echo "${*}" | base64 --decode; }
KEY="FLAVOR"
FILE=${SRCROOT}/Flutter/DartDefineFlavor.xcconfig
test -f $FILE || touch $FILE
IFS=',' read -r -a ENCODED_ITEMS <<< "$DART_DEFINES"
for ENCODED_ITEM in ${ENCODED_ITEMS[#]}
do
DECODED_ITEM=$(decode "$ENCODED_ITEM")
IFS=' ' read -r K V <<< ${DECODED_ITEM//[=]/ };
if [ $K = $KEY ]; then
echo "DART_DEFINE_BUNDLE_SUFFIX=.$V" >> $FILE
break
fi
done
">
<EnvironmentBuildable>
reality:
<ActionContent
title = "Load Dart Define"
scriptText = "#!/bin/bash
function decode() { echo "${*}" | base64 --decode; }
KEY=FLAVOR
FILE=${SRCROOT}/Flutter/DartDefineFlavor.xcconfig
test -f $FILE || touch $FILE
IFS=',' read -r -a ENCODED_ITEMS <<< "$DART_DEFINES"
for ENCODED_ITEM in ${ENCODED_ITEMS[#]}
do
DECODED_ITEM=$(decode "$ENCODED_ITEM")
IFS='=' read -r K V <<< $DECODED_ITEM;
if [ $K = $KEY ]; then
NAME_SUFFIX="DART_DEFINE_NAME_SUFFIX= $V"
BUNDLE_SUFFIX="DART_DEFINE_BUNDLE_SUFFIX=.$V"
echo $NAME_SUFFIX >> $FILE
echo $BUNDLE_SUFFIX >> $FILE
break
fi
done
">
<EnvironmentBuildable>
Related
Assume that I've a complex json file that is used to configurate my project.
Like the json below:
{
"apis": {
"payment": {
"base_url": "https://example.com/"
},
"order": {
"base_url": "https://example.com/"
},
},
"features": {
"authentication": {
"authProviders": true,
"registration": false
}
},
"availableLocales": [
"en",
"es"
]
}
With .Net there's a feature that allows us to override the values based on environment variables.
If I wanted to override the value of apis.payment.base_url I could pass an environment variable: APIS__PAYMENT__BASE_URL and the value would be replaced.
Since I'm currently not using .Net is there any alternatives?
This is what I'm using right now, but this does not fit my needs
FROM code as prepare-build
ENV JQ_VERSION=1.6
RUN wget --no-check-certificate \
https://github.com/stedolan/jq/releases/download/jq-${JQ_VERSION}/jq-linux64 \
-O /tmp/jq-linux64
RUN cp /tmp/jq-linux64 /usr/bin/jq
RUN chmod +x /usr/bin/jq
WORKDIR /code/public
RUN jq 'reduce path(recurse | scalars) as $p (.;setpath($p; "$" + ($p | join("_"))))' \
./configurations/settings.json > ./configurations/settings.temp.json && \
yez | cp ./configurations/settings.temp.json ./configurations/settings.json
WORKDIR /code/deploy
RUN echo "#!/usr/bin/env sh" | tee -a /code/deploy/start.sh > /dev/null && \
echo 'export EXISTING_VARS=$(printenv | awk -F= '\''{print $1}'\'' | sed '\''s/^/\$/g'\'' | paste -sd,);' | tee -a /code/deploy/start.sh > /dev/null && \
echo 'for file in $CONFIGURATIONS_FOLDER;' | tee -a /code/deploy/start.sh > /dev/null && \
echo 'do' | tee -a /code/deploy/start.sh > /dev/null && \
echo ' cat $file | envsubst $EXISTING_VARS | tee $file' | tee -a /code/deploy/start.sh > /dev/null && \
echo 'done' | tee -a /code/deploy/start.sh > /dev/null && \
echo 'nginx -g '\''daemon off;'\''' | tee -a /code/deploy/start.sh > /dev/null
WORKDIR /code
This was I have a problem that, I need to pass all the json paths as environment variables, to override it correctly. If not, the variables will be replaced with the path of it, only.
I think the best approach would be:
Read the environment variables and create a json file with their values, then override the existing json file with the values of the created one.
Does anyone have any thing that could help me achieve this?
To summarize.
In order to make easy to identify which environment variables I should use, let's assume it will have a prefix of SETTINGS.
Example of how I would override values.
JSON PATH
EQUIVALENT ENVIRONMENT VARIABLE
APIS.PAYMENT.BASE_URL
SETTINGS__APIS__PAYMENT__BASE_URL
AVAILABLELOCALES[0]
SETTINGS__AVAILABLELOCALES__0
The task can be solved using jq.
The version is robust against settings that do not match a path in the document.
Variables
SETTINGS__APIS__PAYMENT__BASE_URL=https://example2.com
SETTINGS__AVAILABLELOCALES__0=cs
SETTINGS__UNAVAILABLE__PATH=1
Code
jq 'def settings:
def prepareVariables:
[$ENV | to_entries[] | select(.key | startswith("SETTINGS__"))] # select all variables that starts with "SETTINGS__"
| map(.key |= (. / "__" | map(tonumber? // .))[1:]); # convert variable names to path arrays
[paths(scalars) | [., map(ascii_upcase? // .)]] | # collect all leaf paths from input file and add uppercase path
reduce .[] as $leafPath # add leaf paths to corresponding settings
(prepareVariables; map(select($leafPath[1] == .key) |= . + {path: $leafPath[0]})) |
map(select(has("path"))); # drop settings for unknown paths
. as $input |
reduce settings[] as $setting # apply new settings from variables to input file
($input; . | setpath($setting["path"]; $setting["value"]))
' input.json
Output
{
"apis": {
"payment": {
"base_url": "https://example2.com"
},
"order": {
"base_url": "https://example.com/"
}
},
"features": {
"authentication": {
"authProviders": true,
"registration": false
}
},
"availableLocales": [
"cs",
"es"
]
}
I'm a jq novice, and I'd be very interested in a better jq script, but here's one way to use environment variables to modify a settings.json file.
$ cat settings.json
{
"apis": {
"payment": {
"base_url": "https://example.com/"
},
"order": {
"base_url": "https://example.com/"
}
},
"features": {
"authentication": {
"authProviders": true,
"registration": false
}
},
"availableLocales": [
"en",
"es"
]
}
$ printenv|grep SETTINGS__
SETTINGS__APIS__PAYMENT__BASE_URL=https://example2.com
SETTINGS__AVAILABLELOCALES__0=cs
$ jq -n '
inputs as $i
| [ $i
| ..
| keys_unsorted?
| .[]
| strings
]
| unique as $allKeys
|
def fixCase:
. as $w
| reduce ($allKeys[]|select(length == ($w|length))) as $k
("";. + $k|match($w;"i").string)
;
def envpaths:
[
$ENV
| to_entries[]
| select(.key | startswith("SETTINGS__"))
| [[ (.key|split("__"))[1:][]
| if test("^[0-9]+$") then tonumber else fixCase end
],
.value
]
]
;
reduce envpaths[] as $p ($i; .|setpath($p[0];$p[1]))' settings.json
# the output
{
"apis": {
"payment": {
"base_url": "https://example2.com"
},
"order": {
"base_url": "https://example.com/"
}
},
"features": {
"authentication": {
"authProviders": true,
"registration": false
}
},
"availableLocales": [
"cs",
"es"
]
}
See it work on jqplay.org.
I'm trying to replace a a blank line in a set of text files (*.txt) for a "--" if the previous line matchs a pattern. My code is
awk 'BEGIN{$headerfound=0} { if (/pattern/) {print> FILENAME ; $headerfound=1} else { if((/^\s*$/) && ($headerfound == 1)) { $headerfound=0; print "--" > FILENAME } else {print > FILENAME} } }' *.txt
But for some reason, output is limited to 4kbytes files (if the file is larger, it gets clipped). Do you know where is the limitation?
Thanks,
Ariel
See #glennjackman's comments for problems in your script.
Since you are using GNU awk (you used \s which is gawk-specific) you can use inplace-editing and write your script as (spread out with white space to improve readability):
awk -i inplace '{
if (/pattern/) {
print
headerfound=1
} else {
if((/^\s*$/) && (headerfound == 1)) {
headerfound=0
print "--"
} else {
print
}
}
}' *.txt
but you can do the same thing much more concisely (and awk-ishly) as:
awk -i inplace '
/pattern/ { headerfound=1 }
headerfound && !NF { $0="--"; headerfound=0 }
1' *.txt
If you don't have inplace editing then do it this way:
for file in *.txt; do
awk '
/pattern/ { headerfound=1 }
headerfound && !NF { $0="--"; headerfound=0 }
1' "$file" > tmp$$ &&
mv tmp$$ "$file"
done
You can probably get away with:
suffix=".$$.tmp" '
awk -v suf="$suffix" '
FNR == 1 {outfile = FILENAME suf}
/pattern/ {headerfound = 1}
headerfound && /^[[:blank:]]*$/ {$1 = "--"}
{ print > outfile }
' *.txt
for f in *.txt; do
echo mv "${f}$suffix" "$f"
done
Remove the echo from the for loop if you're satisfied it's working.
Missed the "just after" requirement (using Ed's use of NF to find a blank line):
awk -v suf="$suffix" '
FNR == 1 {outfile = FILENAME suf}
/pattern/ {lineno = FNR}
FNR == lineno+1 && NF == 0 {$0 = "--"}
{ print > outfile }
' *.txt
My usual way to submit a file is:
p4 submit –d “some description” filename
I could do:
p4 submit
and use the editor, but I always have many files open, so that method is inconvenient
Several times, I have mistakenly typed
p4 submit –d "some description"
(forgot the filename)
This submitted dozens of open files to production, with unintended consequences.
Time to panic and spend the afternoon doing damage control.
I would like to prevent p4 -d when the filename is not specified.
If you are using Linux you can define function in your .bashrs file that validates number of arguments and won't let you submit if you miss4th parameter.
function p4()
{
# validate what parameters are passed and if they are correct
# pass them to /opt/perforce/p4 ...
}
Thanks #pitseeker
I created a Perl wrapper "p4s" which checks the arguments and forwards the call to the real "p4 submit".
#!/usr/bin/perl
use warnings;
use strict;
use Capture::Tiny 'capture_merged';
die "Description and file is required!\n" if #ARGV < 2;
my ($description, #files) = #ARGV;
if ( -f $description ) {
die "It looks like you forgot the description before the filenames";
}
my $cmd;
my %summary;
print `date`;
for my $file (#files) {
if ( ! -f $file ) {
$summary{$file} = "File $file not found!";
next;
}
my $pwd = `pwd`;
chomp $pwd;
# print p4 filelog to screen
print `ls -l $file`;
$cmd = "p4 filelog $file | head -n 2";
$cmd = "p4 fstat -T 'headRev' $file";
print $cmd . "\n";
my $filelog = `$cmd`;
print "$filelog" . "\n";
$cmd = "p4 diff -sa $file";
my ($merged, $status) = Capture::Tiny::capture_merged {system($cmd)};
if ( ! $merged ) {
$summary{$file} = "Skipped since the local file does not differ from p4";
next;
}
# p4 submit
$cmd = "p4 submit -r -d \"$description\" $file";
print $cmd . "\n";
($merged, $status) = Capture::Tiny::capture_merged {system($cmd)};
chomp $merged;
print $merged . "\n";
if ( $merged =~ /No files to submit from the default changelist/ ) {
$summary{$file} = "$merged (You may need to 'p4 add' or 'p4 edit' this file)";
next;
}
$summary{$file} = "Success";
}
if ( scalar #files > 0 ) {
print "\nSummary:\n";
for my $file (#files) {
printf "%s %s\n", $file, $summary{$file};
}
}
I'm new to Powershell and am having trouble joining together two scripts I have.
What I want to do is check the length of all the csv files within a particular folder and if any of them are 0 Kb, I want to send off an alert email. So far I have a script which sends an email successfully and I have a script which checks the size successfully, but I am having trouble joining the two together.
Ideally it would send the name of the files which are empty in the body of the email.
The code below checks the file size and if it is greater than 1Kb it returns true.
$file = 'FilePath\File1.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File1.csv Contains Data"} ELSE {"File1.csv is Empty!"}
$file = 'FilePath\File2.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File2.csv Contains Data"} ELSE {"File2.csv is Empty!"}
$file = 'FilePath\File3.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File3.csv Contains Data"} ELSE {"File3.csv is Empty!"}
$file = 'FilePath\File4.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File4.csv Contains Data"} ELSE {"File4.csv is Empty!"}
$file = 'FilePath\FileName5.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File5.csv Contains Data"} ELSE {"File5.csv is Empty!"}
$file = 'FilePath\FileName6.csv'
$Result = if (Test-Path $file) { (Get-Item $file).length -gt 1kb }
if ($Result -eq "True") {"File6.csv Contains Data"} ELSE {"File6.csv is Empty!"}
Below is the email portion
$subject = "Emailtest"
$body = "test"
$emailTo = "jbloggs#Madeup.com"
$emailFrom ="JohnSmith#123.com"
$smtpServer = “mail.madeup.com”
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$credentials=new-object system.net.networkcredential(”username”,”password”)
$smtp.credentials=$credentials.getcredential($smtpserver,"25","basic")
$smtp.Send($emailFrom, $emailTo, $subject, $body)
Thank you for any help.
That's an awful lot of (manual) work just to check for empty files. What happens when you add a seventh - do you have to edit the script?
$EmptyFiles = (Get-childItem -Path $FilePath -Filter *.csv | `
where-object {$_.length -eq 0}|select-object -expandproperty Name)
$MsgBody = "The following files are empty:";
$EmptyFiles | foreach{$MsgBody+="`n$_";};
$MsgBody; # Just to output to console
$secpasswd = ConvertTo-SecureString "password" -AsPlainText -Force
$credentials= New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
$subject = "Emailtest"
$body = "test"
$emailTo = "jbloggs#Madeup.com"
$emailFrom ="JohnSmith#123.com"
$smtpServer = “mail.madeup.com”
send-mailmessage -smtpserver $smtpServer -subject $subject -to $emailto -Credential $credentials -body $MsgBody
Sorry for confusing you,
well, actually i want to send serial message to my arduino which is connected to /dev/ttyACM0 and it can be done by typing this command into terminal
$ echo "Hello Arduino" > /dev/ttyACM0
so, i need my awk to send a command just like that.
Here is my PBH.awk file:
BEGIN{
FS = "[ .]";
RS = "\0";
IGNORECASE = 1;
}{
for (i=1;i<NF;i++){
if(i == 1){
printf("Diketahui : %s\n",$18);}
if($i=="y" && $(i+1)=="=")
{
printf(" Persamaan : %s %s %s %s %s %s %s %s %s %s %s\n",$(i),$(i+1),$(i+2),$(i+3),$(i+4),$(i+5),$(i+6),$(i+7),$(i+8),$(i+9),$(i+10))
inisialisasi = "stty -F /dev/ttyACM0 cs8 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke noflsh -ixon -crtscts"
kirim = "echo \"Field2 contains: $2""\" > /dev/ttyACM0"
print | inisialisasi
print | kirim
}
}
}
and here is the soalPBH.txt:
Persamaan gelombang berjalan pada seutas tali dinyatakan dengan y = 0,02 sin (20 π t – 0,2 π x). Jika x dan y dalam cm dan t dalam sekon, tentukan:
Then i run my awk with
$ awk -f PBH.awk soalPBH.txt
My program doesnt send the text on field number 2.
Is there something wrong with this??
kirim = "echo \"Field2 contains: $2""\" > /dev/ttyACM0"
Its VERY unclear what you're trying to do. Is this it:
$ cat file
field1 field2 field3
$ awk '{printf "echo \"Hello Arduino %s\" > /dev/ttyACM0\n", $2}' file
echo "Hello Arduino field2" > /dev/ttyACM0
If not, clarify your question and provide some clear sample input and expected output.
Given your updated question, just move the quote so $2 is outside of the quotes instead of inside of them, i.e. "$2 instead of $2":
kirim = "echo \"Field2 contains: " $2 "\" > /dev/ttyACM0"
Then tell us if you still have a problem.