How to edit a .property file in powershell - properties-file

I have a application.properties file in following format
application.name=some thing
application.version=4.1.0.1
application.list=abc.def, ghi.jkl
Now my task is to append mno.pqr to application.list
I am able to read it using
$AppProps = convertfrom-stringdata (get-content .\application.properties -raw)
I changed the Application.list value in $AppProps.
How to save it back to original Application.properties file..?

You can try the following:
$AppProps.GetEnumerator() | % { "$($_.Name)=$($_.Value)" } > .\application.properties
Note that > creates UTF-16 LE files (with BOM) by default, so if you want to control the encoding explicitly, pipe to either Out-File or Set-Content using the -Encoding parameter instead.
There is no complementary ConvertTo-StringData, unfortunately, so you have to create your own output formatting (the default output format of a hashtable does not work as a properties file):
ConvertFrom-StringData returns a hashtable, so $AppProps contains one.
$AppProps.GetEnumerator() sends the hashtable's key/value pairs (dictionary entries of type [System.Collections.DictionaryEntry]) one by one through the pipeline.
The .GetEnumerator() call is necessary, because PowerShell treats a hashtable as a single object in a pipeline.
% { "$($_.Name)=$($_.Value)" } constructs the output string for each key/value pair.
Caveats that stem from using ConvertFrom-StringData to read properties files:
Loss of ordering: Since key ordering is not guaranteed in a hashtable, the properties will typically appear in different order when you rewrite the file (at least the first time).
Loss of comments: Comments in the input file (lines whose first non-blank char. is #) are quietly skipped on reading, so you'll lose them when you rewrite the file.

Related

BAT or Powershell For loop through CSV to build a URL

Solved. So my first go at this post was a VERY poorly structured question trying to obfuscate proprietary company information in a very poor manner, and not asking the question well.
Once Walter even got me thinking in the correct direction i worked through the issue. Below was the second issue i was running into and found that the #{key=value} statement was being passed into my url because for some reason my script did not like the header in my csv file. In hindsight, perhaps because i was naming my variable the same as my header. Regardless I worked around it just by using Get-Content rather than Import-CSV.
$aliases = Import-Csv -Path .\aliases.csv
foreach ($alias in $aliases) {
Write-Output ('http://www.' + $($alias) + '.mydomain.com') >> urls.txt
where the contents of aliases.csv is:
alias
Matthew
Mable
Mark
Mary
This is giving me:
http://www.#{alias=Matthew}.mydomain.com
http://www.#{alias=Mable}.mydomain.com
http://www.#{alias=Mark}.mydomain.com
http://www.#{alias=Mary}.mydomain.com
When successful urls.txt should contain:
http://www.Matthew.mydomain.com
http://www.Mable.mydomain.com
http://www.Mark.mydomain.com
http://www.Mary.mydomain.com
NOTE: Edited to clarify use case
In Powershell
Get-Content names.txt | %{"Hello, my name is $_. How are you?"} >> results.txt
By the way, with just a little more effort, you can read more than one variable from a csv file, and substitute all of them for named variables in the text. This turns out to be very useful in a variety of situations.
Edit to conform to your edit
Import-csv ./aliases.csv | %{ "http://www.$($_.alias).mydomain.com"}
Notes:
Once you get used to them, pipelines are the easiest way to process a stream of just about anything.
% is an abbreviation of Foreach-Object (not to be confused with foreach).
The loop will be done once for each object coming out of the pipe. Each object will be a PSCustomObject with a single property named alias.
$() allows evaluation of a subexpression within a double quoted string.
$_ is the current object.
the dot, in this context, separates an object specified from a named property.

Using BQ command line change configuration configuration.load.quote

I want to know how using BQ command line tool I can change configuration of a BigQuery API job. E.g., I want to change configuration.load.quote property from command line tool. Is there is any way. I need this to load a table with field double quote(") inside.
You cannot modify a job once it is created, but I guess what you want is set the quote property when creating the job.
In most cases, bq help <command> will get you what you need. Here's the output of bq help load. As you can see, you just have to specify --quote="'" after the command but before the arguments.
$ bq help load
Python script for interacting with BigQuery.
USAGE: bq.py [--global_flags] <command> [--command_flags] [args]
load Perform a load operation of source into destination_table.
Usage:
load <destination_table> <source> [<schema>]
The <destination_table> is the fully-qualified table name of table to
create, or append to if the table already exists.
The <source> argument can be a path to a single local file, or a
comma-separated list of URIs.
The <schema> argument should be either the name of a JSON file or a
text schema. This schema should be omitted if the table already has
one.
In the case that the schema is provided in text form, it should be a
comma-separated list of entries of the form name[:type], where type
will default to string if not specified.
In the case that <schema> is a filename, it should contain a single
array object, each entry of which should be an object with properties
'name', 'type', and (optionally) 'mode'. See the online documentation
for more detail:
https://developers.google.com/bigquery/preparing-data-for-bigquery
Note: the case of a single-entry schema with no type specified is
ambiguous; one can use name:string to force interpretation as a
text schema.
Examples:
bq load ds.new_tbl ./info.csv ./info_schema.json
bq load ds.new_tbl gs://mybucket/info.csv ./info_schema.json
bq load ds.small gs://mybucket/small.csv name:integer,value:string
bq load ds.small gs://mybucket/small.csv field1,field2,field3
Arguments:
destination_table: Destination table name.
source: Name of local file to import, or a comma-separated list of
URI paths to data to import.
schema: Either a text schema or JSON file, as above.
Flags for load:
/home/David/google-cloud-sdk/platform/bq/bq.py:
--[no]allow_jagged_rows: Whether to allow missing trailing optional columns in
CSV import data.
--[no]allow_quoted_newlines: Whether to allow quoted newlines in CSV import
data.
-E,--encoding: <UTF-8|ISO-8859-1>: The character encoding used by the input
file. Options include:
ISO-8859-1 (also known as Latin-1)
UTF-8
-F,--field_delimiter: The character that indicates the boundary between
columns in the input file. "\t" and "tab" are accepted names for tab.
--[no]ignore_unknown_values: Whether to allow and ignore extra, unrecognized
values in CSV or JSON import data.
--max_bad_records: Maximum number of bad records allowed before the entire job
fails.
(default: '0')
(an integer)
--quote: Quote character to use to enclose records. Default is ". To indicate
no quote character at all, use an empty string.
--[no]replace: If true erase existing contents before loading new data.
(default: 'false')
--schema: Either a filename or a comma-separated list of fields in the form
name[:type].
--skip_leading_rows: The number of rows at the beginning of the source file to
skip.
(an integer)
--source_format: <CSV|NEWLINE_DELIMITED_JSON|DATASTORE_BACKUP>: Format of
source data. Options include:
CSV
NEWLINE_DELIMITED_JSON
DATASTORE_BACKUP
gflags:
--flagfile: Insert flag definitions from the given file into the command line.
(default: '')
--undefok: comma-separated list of flag names that it is okay to specify on
the command line even if the program does not define a flag with that name.
IMPORTANT: flags in this list that have arguments MUST use the --flag=value
format.
(default: '')

how to fetch a data from one file location and to run using tcl code

In tcl how to get the data from one file location and to run that data using TCL code .
for example
In the folder 1 there is config file ,i want to get the informations of config file and i want to execute the information that is present or not,
If the configuration file contains Tcl code, it's just:
# Put the filename in quotes if you want, or in a variable, or ...
source /the/path/to/the/file.tcl
If the file contains Tcl code but you don't trust it, you can use a “safe interpreter” context. This disables many commands, giving a much more restricted set of capabilities that you can then add specific exceptions to (with interp alias):
# Make the context
set i [interp create -safe]
# Set up a way for the context to let the master find out about what to
# really set
interp alias $i configure {} recordConfiguration
proc recordConfiguration args {
puts "configured with $args"
}
# Evaluate the script (note that [source] is hidden by default) in the context
$i invokehidden source /the/path/to/the/file.tcl
# Dispose the context
interp delete $i
If the file isn't Tcl code, you have to parse it. That's a substantially more complex matter, so much so that we'll need to know the format of the file before we can answer.
If you are trying to read data (like text strings) from a file then you'll have to open a channel for that particular file like this:
set fileid [open "path/to/your/file.txt" r]
Read open manual page.
Then you can use gets command to read data from the file through the channel fileid .

Best practice using NSLocalizedString

I'm (like all others) using NSLocalizedStringto localize my app.
Unfortunately, there are several "drawbacks" (not necessarily the fault of NSLocalizedString itself), including
No autocompletition for strings in Xcode. This makes working not only error-prone but also tiresome.
You might end up redefining a string simply because you didn't know an equivalent string already existed (i.e. "Please enter password" vs. "Enter password first")
Similarily to the autocompletion-issue, you need to "remember"/copypaste the comment strings, or else genstring will end up with multiple comments for one string
If you want to use genstring after you've already localized some strings, you have to be careful to not lose your old localizations.
Same strings are scattered througout your whole project. For example, you used NSLocalizedString(#"Abort", #"Cancel action") everywhere, and then Code Review asks you to rename the string to NSLocalizedString(#"Cancel", #"Cancel action") to make the code more consistent.
What I do (and after some searches on SO I figured many people do this) is to have a seperate strings.h file where I #define all the localize-code. For example
// In strings.h
#define NSLS_COMMON_CANCEL NSLocalizedString(#"Cancel", nil)
// Somewhere else
NSLog(#"%#", NSLS_COMMON_CANCEL);
This essentially provides code-completion, a single place to change variable names (so no need for genstring anymore), and an unique keyword to auto-refactor. However, this comes at the cost of ending up with a whole bunch of #define statements that are not inherently structured (i.e. like LocString.Common.Cancel or something like that).
So, while this works somewhat fine, I was wondering how you guys do it in your projects. Are there other approaches to simplify the use of NSLocalizedString? Is there maybe even a framework that encapsulates it?
NSLocalizedString has a few limitations, but it is so central to Cocoa that it's unreasonable to write custom code to handle localization, meaning you will have to use it. That said, a little tooling can help, here is how I proceed:
Updating the strings file
genstrings overwrites your string files, discarding all your previous translations.
I wrote update_strings.py to parse the old strings file, run genstrings and fill in the blanks so that you don't have to manually restore your existing translations.
The script tries to match the existing string files as closely as possible to avoid having too big a diff when updating them.
Naming your strings
If you use NSLocalizedString as advertised:
NSLocalizedString(#"Cancel or continue?", #"Cancel notice message when a download takes too long to proceed");
You may end up defining the same string in another part of your code, which may conflict as the same english term may have different meaning in different contexts (OK and Cancel come to mind).
That is why I always use a meaningless all-caps string with a module-specific prefix, and a very precise description:
NSLocalizedString(#"DOWNLOAD_CANCEL_OR_CONTINUE", #"Cancel notice window title when a download takes too long to proceed");
Using the same string in different places
If you use the same string multiple times, you can either use a macro as you did, or cache it as an instance variable in your view controller or your data source.
This way you won't have to repeat the description which may get stale and get inconsistent among instances of the same localization, which is always confusing.
As instance variables are symbols, you will be able to use auto-completion on these most common translations, and use "manual" strings for the specific ones, which would only occur once anyway.
I hope you'll be more productive with Cocoa localization with these tips!
As for autocompletition for strings in Xcode, you could try https://github.com/questbeat/Lin.
Agree with ndfred, but I would like to add this:
Second parameter can be use as ... default value!!
(NSLocalizedStringWithDefaultValue does not work properly with genstring, that's why I proposed this solution)
Here is my Custom implementation that use NSLocalizedString that use comment as default value:
1 . In your pre compiled header (.pch file) , redefine the 'NSLocalizedString' macro:
// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"
#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key comment:_comment]
2. create a class to implement the localization handler
#import "LocalizationHandlerUtil.h"
#implementation LocalizationHandlerUtil
static LocalizationHandlerUtil * singleton = nil;
+ (LocalizationHandlerUtil *)singleton
{
return singleton;
}
__attribute__((constructor))
static void staticInit_singleton()
{
singleton = [[LocalizationHandlerUtil alloc] init];
}
- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
// default localized string loading
NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];
// if (value == key) and comment is not nil -> returns comment
if([localizedString isEqualToString:key] && comment !=nil)
return comment;
return localizedString;
}
#end
3. Use it!
Make sure you add a Run script in your App Build Phases so you Localizable.strings file will be updated at each build, i.e., new localized string will be added in your Localized.strings file:
My build phase Script is a shell script:
Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyClassesFolder
So when you add this new line in your code:
self.title = NSLocalizedString(#"view_settings_title", #"Settings");
Then perform a build, your ./Localizable.scripts file will contain this new line:
/* Settings */
"view_settings_title" = "view_settings_title";
And since key == value for 'view_settings_title', the custom LocalizedStringHandler will returns the comment, i.e. 'Settings"
Voilà :-)
In Swift I'm using the following, e.g. for button "Yes" in this case:
NSLocalizedString("btn_yes", value: "Yes", comment: "Yes button")
Note usage of the value: for the default text value. The first parameter serves as the translation ID. The advantage of using the value: parameter is that the default text can be changed later but the translation ID remains the same. The Localizable.strings file will contain "btn_yes" = "Yes";
If the value: parameter was not used then the first parameter would be used for both: for the translation ID and also for the default text value. The Localizable.strings file would contain "Yes" = "Yes";. This kind of managing localization files seems to be strange. Especially if the translated text is long then the ID is long as well. Whenever any character of the default text value is changed, then the translation ID gets changed as well. This leads to issues when external translation systems are used. Changing of the translation ID is understood as adding new translation text, which may not be always desired.
I wrote a script to help maintaining Localizable.strings in multiple languages. While it doesn't help in autocompletion it helps to merge .strings files using command:
merge_strings.rb ja.lproj/Localizable.strings en.lproj/Localizable.strings
For more info see:
https://github.com/hiroshi/merge_strings
Some of you find it useful I hope.
If anyone looking for a Swift solution. You may want to check out my solution I put together here: SwiftyLocalization
With few steps to setup, you will have a very flexible localization in Google Spreadsheet (comment, custom color, highlight, font, multiple sheets, and more).
In short, steps are: Google Spreadsheet --> CSV files --> Localizable.strings
Moreover, it also generates Localizables.swift, a struct that acts like interfaces to a key retrieval & decoding for you (You have to manually specify a way to decode String from key though).
Why is this great?
You no longer need have a key as a plain string all over the places.
Wrong keys are detected at compile time.
Xcode can do autocomplete.
While there're tools that can autocomplete your localizable key. Reference to a real variable will ensure that it's always a valid key, else it won't compile.
// It's defined as computed static var, so it's up-to-date every time you call.
// You can also have your custom retrieval method there.
button.setTitle(Localizables.login.button_title_login, forState: .Normal)
The project uses Google App Script to convert Sheets --> CSV , and Python script to convert CSV files --> Localizable.strings You can have a quick look at this example sheet to know what's possible.
with iOS 7 & Xcode 5, you should avoid using the 'Localization.strings' method, and use the new 'base localisation' method. There are some tutorials around if you google for 'base localization'
Apple doc : Base localization
#define PBLocalizedString(key, val) \
[[NSBundle mainBundle] localizedStringForKey:(key) value:(val) table:nil]
Myself, I'm often carried away with coding, forgetting to put the entries into .strings files. Thus I have helper scripts to find what do I owe to put back into .strings files and translate.
As I use my own macro over NSLocalizedString, please review and update the script before using as I assumed for simplicity that nil is used as a second param to NSLocalizedString. The part you'd want to change is
NSLocalizedString\(#(".*?")\s*,\s*nil\)
Just replace it with something that matches your macro and NSLocalizedString usage.
Here comes the script, you only need Part 3 indeed. The rest is to see easier where it all comes from:
// Part 1. Get keys from one of the Localizable.strings
perl -ne 'print "$1\n" if /^\s*(".+")\s*=/' myapp/fr.lproj/Localizable.strings
// Part 2. Get keys from the source code
grep -n -h -Eo -r 'NSLocalizedString\(#(".*?")\s*,\s*nil\)' ./ | perl -ne 'print "$1\n" if /NSLocalizedString\(#(".+")\s*,\s*nil\)/'
// Part 3. Get Part 1 and 2 together.
comm -2 -3 <(grep -n -h -Eo -r 'NSLocalizedString\(#(".*?")\s*,\s*nil\)' ./ | perl -ne 'print "$1\n" if /NSLocalizedString\(#(".+")\s*,\s*nil\)/' | sort | uniq) <(perl -ne 'print "$1\n" if /^\s*(".+")\s*=/' myapp/fr.lproj/Localizable.strings | sort) | uniq >> fr-localization-delta.txt
The output file contains keys that were found in the code, but not in the Localizable.strings file. Here is a sample:
"MPH"
"Map Direction"
"Max duration of a detailed recording, hours"
"Moving ..."
"My Track"
"New Trip"
Certainly can be polished more, but thought I'd share.

gzip several files and pipe them into one input

I have this program that takes one argument for the source file and then it parse it. I have several files gzipped that I would like to parse, but since it only takes one input, I'm wondering if there is a way to create one huge file using gzip and then pipe it into the only one input.
Use zcat - you can provide it with multiple input files, and it will de-gzip them and then concatenate them just like cat would. If your parser supports piped input into stdin, you can just pipe it directly; otherwise, you can just redirect the output to a file and then invoke your parser program on that file.
If the program actually expects a gzip'd file, then just pipe the output from zcat to gzip to recompress the combined file into a single gzip'd archive.
http://www.mkssoftware.com/docs/man1/zcat.1.asp