LESSCHARSET=utf-8 less doesn't seem to work - utf-8

I'm trying to view a UTF-8 text file/stream in less, and even if I invoke it like this:
cat file | LESSCHARSET=utf-8 less
the non-ASCII compatible UTF-8 characters don't display correctly. Instead, their hex values appear highlighted in brackets, e.g. <F4>.
The reading the same text in vim with UTF-8 encoding poses no problems. So I'm thinking something is wrong with the way I'm invoking less.
My locale output is the following
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
My less version is the one installed by XCode on OSX Leopard:
$ less --version | sed 's/^/ /'
less 394
Copyright (C) 1984-2005 Mark Nudelman
less comes with NO WARRANTY, to the extent permitted by law.
For information about the terms of redistribution,
see the file named README in the less distribution.
Homepage: http://www.greenwoodsoftware.com/less
locale -a | grep US | sed 's/^/ /' outputs the following:
en_AU.US-ASCII
en_CA.US-ASCII
en_GB.US-ASCII
en_NZ.US-ASCII
en_US
en_US.ISO8859-1
en_US.ISO8859-15
en_US.US-ASCII
en_US.UTF-8

What does the locale command output? Is it a UTF-8 locale?
Are you sure your terminal is set to display UTF-8?
Does echo -e '\xe2\x82\xac' produce the € (euro) sign?
Is the locale that you have set even installed on the system? Is it
present in the list that locale -a outputs?
What version of less are you using? (Run less --version to find out.)
Really, really old versions did not even support LESSCHARSET. This
is less likely to be the case, because I have a Debian "sarge" system with
less version 382, and it does not even need LESSCHARSET if the locale is
set correctly.

My guess is that your file isn't UTF8 but rather ISO8859. (Is the <F4> character supposed to be a 'ô'?)
Start an xterm with LANG=en_US.ISO-8859-1 xterm. Then verify the locale (the output of locale should be something like en_US.ISO-8859-1). Then use less to view the file. Does it display correctly?
Note that it isn't enough to just use LESSCHARSET=iso8859 without starting a new terminal. LESSCHARSET tells less to think that the terminal can interpret iso8859, but your terminal probably displays UTF8, since the euro sign displays correctly. But as \xf4 isn't a valid utf8 character, the terminal will probably show something like '�'.

On Mac OS a charset name have to be in upper case:
bash-4.4$ less --version
less 458 (POSIX regular expressions)
Copyright (C) 1984-2012 Mark Nudelman
bash-4.4$ LESSCHARSET=cp1251 less
invalid charset name
bash-4.4$ LESSCHARSET=CP1251 less
Missing filename ("less --help" for help)
Here I found a list of charsets:
{ "ascii", NULL, "8bcccbcc18b95.b" },
{ "utf-8", &utf_mode, "8bcccbcc18b95.b126.bb" },
{ "iso8859", NULL, "8bcccbcc18b95.33b." },
{ "latin3", NULL, "8bcccbcc18b95.33b5.b8.b15.b4.b12.b18.b12.b." },
{ "arabic", NULL, "8bcccbcc18b95.33b.3b.7b2.13b.3b.b26.5b19.b" },
{ "greek", NULL, "8bcccbcc18b95.33b4.2b4.b3.b35.b44.b" },
{ "greek2005", NULL, "8bcccbcc18b95.33b14.b35.b44.b" },
{ "hebrew", NULL, "8bcccbcc18b95.33b.b29.32b28.2b2.b" },
{ "koi8-r", NULL, "8bcccbcc18b95.b." },
{ "KOI8-T", NULL, "8bcccbcc18b95.b8.b6.b8.b.b.5b7.3b4.b4.b3.b.b.3b." },
{ "georgianps", NULL, "8bcccbcc18b95.3b11.4b12.2b." },
{ "tcvn", NULL, "b..b...bcccbccbbb7.8b95.b48.5b." },
{ "TIS-620", NULL, "8bcccbcc18b95.b.4b.11b7.8b." },
{ "next", NULL, "8bcccbcc18b95.bb125.bb" },
{ "dos", NULL, "8bcccbcc12bc5b95.b." },
{ "windows-1251", NULL, "8bcccbcc12bc5b95.b24.b." },
{ "windows-1252", NULL, "8bcccbcc12bc5b95.b.b11.b.2b12.b." },
{ "windows-1255", NULL, "8bcccbcc12bc5b95.b.b8.b.5b9.b.4b." },
{ "ebcdic", NULL, "5bc6bcc7bcc41b.9b7.9b5.b..8b6.10b6.b9.7b9.8b8.17b3.3b9.7b9.8b8.6b10.b.b.b." },
{ "IBM-1047", NULL, "4cbcbc3b9cbccbccbb4c6bcc5b3cbbc4bc4bccbc191.b" },
{ NULL, NULL, NULL }
and a list of corresponding aliases for them:
{ "UTF-8", "utf-8" },
{ "ANSI_X3.4-1968", "ascii" },
{ "US-ASCII", "ascii" },
{ "latin1", "iso8859" },
{ "ISO-8859-1", "iso8859" },
{ "latin9", "iso8859" },
{ "ISO-8859-15", "iso8859" },
{ "latin2", "iso8859" },
{ "ISO-8859-2", "iso8859" },
{ "ISO-8859-3", "latin3" },
{ "latin4", "iso8859" },
{ "ISO-8859-4", "iso8859" },
{ "cyrillic", "iso8859" },
{ "ISO-8859-5", "iso8859" },
{ "ISO-8859-6", "arabic" },
{ "ISO-8859-7", "greek" },
{ "IBM9005", "greek2005" },
{ "ISO-8859-8", "hebrew" },
{ "latin5", "iso8859" },
{ "ISO-8859-9", "iso8859" },
{ "latin6", "iso8859" },
{ "ISO-8859-10", "iso8859" },
{ "latin7", "iso8859" },
{ "ISO-8859-13", "iso8859" },
{ "latin8", "iso8859" },
{ "ISO-8859-14", "iso8859" },
{ "latin10", "iso8859" },
{ "ISO-8859-16", "iso8859" },
{ "IBM437", "dos" },
{ "EBCDIC-US", "ebcdic" },
{ "IBM1047", "IBM-1047" },
{ "KOI8-R", "koi8-r" },
{ "KOI8-U", "koi8-r" },
{ "GEORGIAN-PS", "georgianps" },
{ "TCVN5712-1", "tcvn" },
{ "NEXTSTEP", "next" },
{ "windows", "windows-1252" }, /* backward compatibility */
{ "CP1251", "windows-1251" },
{ "CP1252", "windows-1252" },
{ "CP1255", "windows-1255" },
{ NULL, NULL }

Try the command file file.txt.  If, for example, the output is "ISO-8859 English text" then change the encoding of the file from ISO-8859 to UTF-8 via the command iconv -f ISO-8859-1 -t UTF-8 -o testfile.txt file.txt.  If less testfile.txt displays correctly, finish with mv testfile.txt file.txt.

less -r displays the file correctly for me.
-r or --raw-control-chars
Causes "raw" control characters to be displayed. The default is
to display control characters using the caret notation; for
example, a control-A (octal 001) is displayed as "^A". Warning:
when the -r option is used, less cannot keep track of the actual
appearance of the screen (since this depends on how the screen
responds to each type of control character). Thus, various dis-
play problems may result, such as long lines being split in the
wrong place.

Worked for me:
f='path/to/file/filename.extension'; LESSCHARSET=`file -b --mime-encoding ${f}|tr '[:lower:]' '[:upper:]'` less ${f}

Related

Assigning the values to array from jq and iterate over the values using cb commands

I have the below json in a file from which I wanted to take the "ids" from all price object and put into an array variable.
{
"documentType": "Prices",
"fullCharges": [
{
"ResourceId": null,
"price": {
"href": null,
"id": "8ddaaabc92bc"
},
"product": {
"href": null,
"id": "123"
}
},
{
"price": {
"href": null,
"id": "326f0f273258"
},
"product": {
"href": null,
"id": "123"
}
}
],
"createdBy": "test",
"createdOn": "2021-10-05T00:00:55Z",
"currentSeqNum": 2
}
I am using the below query but the result is coming in the proper way.
priceIds=$(jq -r .fullCharges[].price.id ${file})
Using above command, it is behaving like a single value, not like array. If I print the priceId value it is only showing the last value.
326f0f273258 instead of 8ddaaabc92bc 326f0f273258
And when I am looping over it, again it is behaving as a single value.
for price in "${priceIds[#]}"
do
printf "$price"
cbq -u Administrator -p Administrator -e "http://localhost:8093" --script="select * FROM \`com.src.test.price\` where docId==\"$price\";"
done
Output command of above loop: select * FROM `com.src.test.price` where documentId=="8ddaaabc92bc 326f0f273258";
There should be 2 command like these
select * FROM `com.src.test.price` where documentId=="8ddaaabc92bc"
select * FROM `com.src.test.price` where documentId=="326f0f273258"
Using extra parens, it helped me to create array.
Using the below sed command over array item variable, i was able to remove extra line from it.
price=$(echo "$price" | sed 's/^[ \n]*//;s/[ \n]*$//')

How to get my cursor on a new line after the highlight line of OhMyPosh theme?

I want the cursor to be on a new line
currently it is on the same line as the highlight line.
I have tried adding "newline" : true, but it didn't work.
How can I resolve it ?
I'm pretty new to Oh My Posh installed on my Mac. I've found very little about what to do to add a \n at the end of the prompt in the documentation. I've even tried what I've read in this dev.to powershell article by adding this block at the end of the json file...
...
{
"type": "prompt",
"alignment": "left",
"newline": true,
"segments": [
{
"type": "text",
"style": "plain",
"foreground": "#007ACC",
"properties": {
"prefix": "",
"text": "\uE602"
}
}
]
}
...
...but it didn't work for me. At best I can only get a "newline": true with an empty line between executed commands, e.g.:
 ~/Downloads  $
 ~/Downloads  $
instead of the desired
 ~/Downloads 
$
 ~/Downloads 
$
SO!
Even if it might be the less elegant workaround I simply found any "trailing_diamond": "\ue0b4" in the omp.json file and (by tries and errors) added to almost all them \n$:
...
"trailing_diamond": "\ue0b4\n$ "
...
EDIT:
Found a new solution
I stumbled upon a GitHub Issue comment by JanDeDobbeleer (owner of JanDeDobbeleer/oh-my-posh) which is something I'm pretty sure I hadn't found on the documentation, especially in the arguments listed in Type.
Adding a new block with just type property and just newline as argument works like a the charm 😉:
{
"type": "newline"
},
Despite what I thought, the last approach is now deprecated!
The solution would still be to use a block (first and last examples) as the last item in the blocks array/list
{
"$schema": ... ,
...
"blocks": [
{
"type": "prompt",
"alignment": "left",
"segments": [
...
]
},
{
...
},
{
"alignment": "left",
"newline": true,
"segments": [{
"foreground": "#007ACC",
"style": "plain",
"template": "\ue602 ",
"type": "text"
}],
"type": "prompt"
},
]
}
Check first your #function Prompt() in your profile path.
If it includes, as shown here, $nonewline, then you might have to set nonewline to false, instead of newline to true.

Parsing a JSON array with jq

I need to parse out specific information from the following JSON example bellow using jq. depending on the 'repo' I need to be able to parse from the properties array all 'key' & 'values' and associated with the repository. For example the repo "libs-production-local" would need to parse out any properties key with 'prod' in the string and its associated date value. has to be jq and run in .sh.
{
"results":[
{
"repo":"libs-production-local",
"path":"com/company/version",
"name":"sql.21.tar",
"type":"file",
"size":"40123",
"created":"date",
"created_by":"someone",
"modified":"date",
"modified_by":"someone",
"updated":"date",
"depth":4,
"actual_md5":"asdflsdf23a4324234",
"orginal_sha1":"sadlkfjsdklfjsadf",
"properties":[
{
"key":"deploy.uat",
"value":"2018-09-23"
},
{
"key":"deploy.prod.TLE",
"value":"2018-10-20"
},
{
"key":"deploy.prodXYZ",
"value":"2018-10-20"
},
{
"key":"deploy.prodPDQ",
"value":"2018-10-20"
},
{
"key":"deploy.prod.ABC",
"value":"2018-10-21"
},
{
"key":"businessUnit.name",
"value":"IndivdualName"
},
{
"key":"deploy.qa.ser2",
"value":"2018-10-20"
},
{
"key":"deploy.qa.ser1",
"value":"2018-11-23"
},
{
"key":"build.timestamp",
"value":"1510850899004"
}
],
"virtual_repos":[
"libs-production "
]
},
{
"repo":"libs-production-local",
"path":"com/company/version",
"name":"sql.22.tar",
"type":"file",
"size":"40123",
"created":"date",
"created_by":"someone",
"modified":"date",
"modified_by":"someone",
"updated":"date",
"depth":4,
"actual_md5":"asdflsdf23a4324234",
"orginal_sha1":"sadlkfjsdklfjsadf",
"properties":[
{
"key":"deploy.prodPDQ",
"value":"2018-10-22"
},
{
"key":"deploy.prodABC",
"value":"2018-10-20"
},
{
"key":"businessUnit.name",
"value":"IndivdualName"
},
{
"key":"deploy.qa",
"value":"2018-10-20"
},
{
"key":"deploy.dev",
"value":"2018-11-19"
}
],
"virtual_repos":[
"libs-production "
]
}
],
"range":{
"start_pos":0,
"end_pos":479,
"total":479
}
}
I've tried a number of ways to do this (including this one) and nothing works.
jq -r '.results[] | ( .properties |map(select(.key[] contains ("prod")) '
I solved it like this:
jq -r '[ .results[].properties[] | select(.key | contains("prod")) ]'
This grabs all key-value pairs from each result's properties array. It then selects those that contain "prod" in the key, and returns an array of those keys and values. Given your example input from above, this is the return value:
[
{
"key": "deploy.prod.TLE",
"value": "2018-10-20"
},
{
"key": "deploy.prodXYZ",
"value": "2018-10-20"
},
{
"key": "deploy.prodPDQ",
"value": "2018-10-20"
},
{
"key": "deploy.prod.ABC",
"value": "2018-10-21"
},
{
"key": "deploy.prodPDQ",
"value": "2018-10-22"
},
{
"key": "deploy.prodABC",
"value": "2018-10-20"
}
]
Is that close to what you're looking for?

How to go to the correct filemaker layout given a layout id?

A FileMaker snapshot file has a layout id. However, using the go to layout number does not work as I had expected.
Set Variable [$json; Value:Get(ScriptParameter)]
Set Variable [$layout_id; Value:JSONGetElement ( $json ; "UIState.Layout.#id" )]
Go to Layout [$layout_id] // layout number by calculation
// ends up on a completely different layout than the one the snapshot file opens.
I've discovered that the layout id and layout number are two different numbers ... which is why the go-to layout number script step failed.
The JSON string used as a parameter for the above script is.
{
"UIState": {
"UniversalPathList": "fmnet:/10.1.1.63/Balanced.fmp12\nfmnet:/10.1.1.220/Balanced.fmp12\nfmnet:/169.254.254.47/Balanced.fmp12\nfilemac:/Macintosh HD/source/fmp16/Balanced.fmp12",
"Rows": {
"#rowCount": "1",
"#baseTableId": "131",
"#text": "21383239"
},
"Layout": {
"#id": "2"
},
"View": [
],
"SelectedRow": {
"#id": "21383239"
},
"StatusToolbar": {
"#visible": "True"
},
"Mode": {
"#value": "browseMode"
},
"SortList": {
"#Maintain": "True",
"#value": "False"
}
}
}
Which can be run from the command line. Example
open 'fmp://filemaker.server/Balanced.fmp12?script=snapshot_link&param={ "UIState": { "UniversalPathList": "fmnet:/10.1.1.63/Balanced.fmp12\nfmnet:/10.1.1.220/Balanced.fmp12\nfmnet:/169.254.254.47/Balanced.fmp12\nfilemac:/Macintosh HD/source/fmp16/Balanced.fmp12", "Rows": { "#rowCount": "1", "#baseTableId": "131", "#text": "21383239" }, "Layout": { "#id": "2" }, "View": [], "SelectedRow": { "#id": "21383239" }, "StatusToolbar": { "#visible": "True" }, "Mode": { "#value": "browseMode" }, "SortList": { "#Maintain": "True", "#value": "False" } } }'
What would be a good way to find the right layout to display in FileMaker given a valid layout id?
I believe you can calculate the layout number by finding the index number of a given layout ID in the list returned by the LayoutIDs function, say =
Let (
listOfIDs = LayoutIDs ( "" )
;
ValueCount ( Left ( listOfIDs ; Position ( ¶ & listOfIDs & ¶ ; ¶ & $layout_ID & ¶ ; 1 ; 1 ) ) )
)

change varible inside json file using bash [duplicate]

This question already has answers here:
How do I use sed to change my configuration files, with flexible keys and values?
(8 answers)
Closed 4 years ago.
I have total 3 environment dev, stag and Prod all environment have config.json like this
{
"braintree": {
"merchantid": "MERCHANTID",
"publickey": "PUBLICKEY",
"privatekey": "PRIVATEKEY"
},
"karix": {
"url": "URL",
"pass": "PASS",
"user": "USER"
},
"fikarix": {
"source": "SOURCE"
},
"mailgun": {
"api_key": "API_KEY",
"domain": "DOMAIN",
"apikey": "APIKEY"
},
"paymentrails": {
"key": "KEY",
"environment": "ENVIRONMENT",
"secret": "SECRET"
}
}
Now I want to convert it into like this for all environment using shell script
dev environment config.json
{
"braintree": {
"merchantid": "dev_MERCHANTID",
"publickey": "dev_PUBLICKEY",
"privatekey": "dev_PRIVATEKEY"
},
"karix": {
"url": "dev_URL",
"pass": "dev_PASS",
"user": "dev_USER"
},
"fikarix": {
"source": "dev_SOURCE"
},
"mailgun": {
"api_key": "dev_API_KEY",
"domain": "dev_DOMAIN",
"apikey": "dev_APIKEY"
},
"paymentrails": {
"key": "dev_KEY",
"environment": "dev_ENVIRONMENT",
"secret": "dev_SECRET"
}
}
How I can get this using sed or any other solution?
sed 's/: "/: "dev_/g' config.json
using sed u can do
Edit:
To insert pass -i
sed -i 's/: "/: "dev_/g' config.json

Resources