Closed. This question is not about programming or software development. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 23 days ago.
Improve this question
command
root#controlplane:~$ kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"26", GitVersion:"v1.26.0", GitCommit:"b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d", GitTreeState:"clean", BuildDate:"2022-12-08T19:57:06Z", GoVersion:"go1.19.4", Compiler:"gc", Platform:"linux/amd64"}
root#controlplane:~$ ^C
root#controlplane:~$
I want result like this
{
"Major":"1",
"Minor":"26",
"GitVersion":"v1.26.0",
"GitCommit":"b46a3f887ca979b1a5d14fd39cb1af43e7e5d12d",
"GitTreeState":"clean",
"BuildDate":"2022-12-08T19:57:06Z",
"GoVersion":"go1.19.4",
"Compiler":"gc",
"Platform":"linux//amd64"
}
you can use an option that kubeadm has.
$ kubeadm version -o json
{
"clientVersion": {
"major": "1",
"minor": "20",
"gitVersion": "v1.20.4",
"gitCommit": "e87da0bd6e03ec3fea7933c4b5263d151aafd07c",
"gitTreeState": "clean",
"buildDate": "2021-02-18T16:09:38Z",
"goVersion": "go1.15.8",
"compiler": "gc",
"platform": "linux/amd64"
}
}
If you want the output to be exactly like above, it is possible using jq.
$ kubeadm version -o json | jq '.clientVersion'
{
"major": "1",
"minor": "20",
"gitVersion": "v1.20.4",
"gitCommit": "e87da0bd6e03ec3fea7933c4b5263d151aafd07c",
"gitTreeState": "clean",
"buildDate": "2021-02-18T16:09:38Z",
"goVersion": "go1.15.8",
"compiler": "gc",
"platform": "linux/amd64"
}
You can use sed to format the output as per your requirement.
$ kubeadm version | sed -e 's/{/\n{\n\t /g' -e 's/,/,\n\t/g' -e 's/}/\n}/g' | tail -n +2
Result
{
Major:"1",
Minor:"23",
GitVersion:"v1.23.4",
GitCommit:"e6c093d87ea4cbb530a7b2ae91e54c0842d8308a",
GitTreeState:"clean",
BuildDate:"2022-02-16T12:36:57Z",
GoVersion:"go1.17.7",
Compiler:"gc",
Platform:"linux/amd64"
}
Explanation:
sed can be used to search and replace in strings/files/STDOUT.
In sed 's/search_parameter/replace_parameter/g', s stands for search and g means to replace globally (If g is not specified then it would replace only first instance of the search term matched) and -e allows you to specify multiple sed commands/scripts in a single sed command.
So here is a breakdown of the above command:
-e 's/{/\n{\n\t /g' - search for { and replace { with { followed by a new line and tab.
-e 's/,/,\n\t/g' - search for , and replace , with , followed by a new line and tab.
-e 's/}/\n}/g' - search for } and replace } with new line followed by }.
tail -n +2 - It will print everything excluding the first line.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 4 years ago.
Improve this question
Can someone tell me what am I doing wrong here? It seems to work on my mac shell but does not work on linux box it seems. Looks like different version of awk? I want to make sure my code works on the linux version.
echo -e "${group_values_with_counts}" | awk '$1>='${value2}' { print "{\"count\":\""$1"\",\"type\":\""$2"\"}" }'
21:19:41 awk: $1>= { print "{\"count\":\""$1"\",\"type\":\""$2"\"}" }
21:19:41 awk: ^ syntax error
You're trying to pass the value of a shell variable into awk the wrong way and using a non-portable echo. The right way (assuming value2 doesn't contain any backslashes) is:
printf '%s\n' "$group_values_with_counts" |
awk -v value2="$value2" '$1>=value2{ print "{\"count\":\""$1"\",\"type\":\""$2"\"}" }'
If value2 can contains backslashes and you want them treated literally (e.g. you do not want \t converted to a tab character) then you need to pass it in using ENVIRON or ARGV. See http://cfajohnson.com/shell/cus-faq-2.html#Q24.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I have a text file of 75000 items, 2 lines for each item. line 1 has an identifier, line 2 a text string.
I need to remove 130 items, random identifiers that I have in a list or can put in a file.
I can carry out the removal for one item, but not for more than one.
I tried piping the identifiers and get an empty output file.
I tried repeated commands of sed -e 'expression' inputfile > outfile. This works, but requires a new output file that then becomes the inputfile for the next iteration and so on. this might be the last resort.
I tried sed -i in iteration; this crashes and the error is that there is no file by the name of the inputfile. Which is clearly not the case, as I can see it, ls it and grep the number of identifiers in it. Only sed can't seem to read it.
I even found a python/biopython script online for this exact problem, it is very simple and does not give error messages, but it also removes only the first item.
I think it has something to do with file properties/temporary files that don't really exist (?).
I am using Ubuntu 12.04 'Precise'
How can I get around this issue?
quick and dirty (no check if modification file is created, ...)
sed
Assuming there is no special meta character in your pattern list
sed 's#.*#/&/{N;d;}#' YourListToExclude > /tmp/exclude.sed
sed -f /tmp/exclude.sed YourDataFile > /tmp/YourDataFile.tmp
mv /tmp/YourDataFile.tmp YourDataFile
rm /tmp/exclude.sed
awk
awk 'FNR==NR{ex=(ex==""?"":ex"|")$0;next}$0!~ex{print;getline;print;next}{getline}' YourListToExclude YourDataFile > /tmp/YourDataFile.tmp
mv /tmp/YourDataFile.tmp YourDataFile
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I'm working on redHat linux.
I've a file which looks like :
$vi filename
Jan,1,00:00:01,someone checked your file
Jan,3,09:38:02,applebee
Jan,16,10:20:03, ****************
Jan,18,03:04:03, ***************
I want the output to look like:
2015/01/01,00:00:01,someone checked your file
2015/01/03,3,09:38:02,applebee
2015/01/16,16,10:20:03, ****************
2015/01/18,03:04:03, ***************
Please help me to do this. Thanks
If you have GNU date, try:
$ awk -F, '{cmd="date -d \""$1" "$2"\" +%Y/%m/%d"; cmd|getline d; print d","$3","$4; close(cmd)}' file
2015/01/01,00:00:01,someone checked your file
2015/01/03,09:38:02,applebee
2015/01/16,10:20:03, ****************
2015/01/18,03:04:03, ***************
This approach cannot be used with the BSD (OSX) version of date because it does not support any comparable -d option.
How it works
awk implicitly loops over lines of input, breaking each line into fields.
-F,
This tells awk to use a comma as the field separator
cmd="date -d \""$1" "$2"\" +%Y/%m/%d"
This creates a string variable, cmd, and contains a date command. I am assuming that you have GNU date.
cmd|getline d
This runs the command and captures the output in variable d.
print d","$3","$4
This prints the output that you asked for.
close(cmd)
This closes the command.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this question
It's now hard to write one without the capability of freezing the header, like
function viewcsv() {
cat $1 | sed -e "s/,,/, ,/g" | column -s, -t | less -#2 -N -S
}
But is there a utility that allows me to freeze the header, or change the one above to allow it?
[EDIT:] by freezing the header I mean when I scroll up and down with "less", the first line remains there on the top of the screen. Those are usually the header information I want to see even when scrolling down thousands of lines, such as "Date", "Symbol", etc.
I adapted this How to scroll large datafile while keeping header to your wishes:
vim -R -u NONE -N +'map <right> 2zl
map <left> 2zh
map q :qa<CR>
se nu sbo=hor scb nowrap
1sp
winc w
' <(sed -e "s/,,/, ,/g" $1|column -ts,)
-R Readonly mode.
-u NONE all
initializations from files and environment variables are
skipped (they could interfere with the working of e. g. winc w)
-N Not compatible mode (otherwise key names like <right> might not work)
map <right> 2zl to make → scroll horizontally like less -#2
map <left> 2zh to make ← scroll horizontally like less -#2
map q :qa<CR> to make Q quit like less
se nu sbo=hor scb nowrap set options:
'number' - Print the line number in front of each line.
'scrollopt'=hor - Bind horizontal scrolling for 'scrollbind' windows
'scrollbind' - to scroll the header line together with the rest of the data
'nowrap' - lines will not wrap
and only part of long lines will be displayed.
1sp Split current window in two (new window has 1 line, the header)
winc w move cursor to body window
Off the top of my head, you could tailor the less prompt to display the CSV headers instead of the usual prompt.
viewcsv () {
less -PM"$(sed -n 's/,/ /gp;q' "$1")" -M -N -S "$1"
}
(You can still see where you are in the file with = -- I suppose you could replace the short or medium prompt just as well.)
If your data contains percent signs or question marks, they will need to be escaped, as these have a special meaning in the less prompt definition. See the description of the -P option and the section PROMPTS in the less manual for details.
Maybe you could even throw in some terminal escape sequences to get the prompt (or part of it) displayed at the top of the screen, but the trivial solution would superimpose the prompt over data you want to see.
Are you just asking about not changing the first line? (It's not at all clear to me what you mean by 'freezing', but 'not modifying' seems like a reasonable interpretation.)
viewcsv() {
sed -e "1!s/,,/, ,/g" "$1" | column -s, -t | less -#2 -N -S
}
(Removed the redundant keyword 'function' and the UUOC. The relevant addition is the address scope 1! in sed.)
Or perhaps you mean that you want the first line to not go through column:
viewcsv() {
{ sed 1q "$1"; sed -e 1d -e 's/,,/, ,/g' "$1" |
column -s, -t; } | less -#2 -N -S
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Improve this question
I'm trying to do three things with the mv command, but not sure it's possible? Probably need a script. not sure how to write it. All files are in same folder.
1) Files ending with v9.zip should just be .zip (the v9 removed)
2) Files containing _ should be -
3) Files with Uppercase letter next to a lowercase letter (or lowercase next to an Uppercase) should have a space between them. So MoveOverNow would be Move Over Now and ruNaway would be ruN away
[A-Z][a-z] or [a-z][A-Z] becomes [A-Z] [a-z] and [a-z] [A-Z]
There's a rename command provided with most Debian/Ubuntu based distros which was written by Robin Barker based on Larry Wall's original code from around 1998(!).
Here's an excerpt from the documentation:
"rename" renames the filenames supplied according to the rule specified as the first argument. The perlexpr argument is a Perl expression which is expected to modify the $_ string in Perl for at least some of the filenames
specified. If a given filename is not modified by the expression, it will not be renamed. If no filenames are given on the command line, filenames will be read via standard input.
For example, to rename all files matching "*.bak" to strip the extension, you might say
rename 's/\.bak$//' *.bak
To translate uppercase names to lower, you'd use
rename 'y/A-Z/a-z/' *
It uses perl so you can use perl expressions to match the pattern, in fact I believe it works much like tchrist's scripts.
One other really useful set of tools for bulk file renaming is the renameutils collection by Oskar Liljeblad. The source code is hosted by the Free Software Foundation. Additionally many distros (especially Debian/Ubuntu based distros) have a renameutils package with these tools.
On one of those distros you can install it with:
$ sudo apt-get install renameutils
And then to rename files just run this command:
$ qmv
It will pop open a text editor with the list of files, and you can manipulate them with your editor's search and replace function.
I haven't tested these, so I put echo at the front of the commands so you can try them before removing the echo to run them for real.
for f in *v9.zip; do echo mv "${f}" "${f%v9.zip}.zip"; done
for f in *_*; do echo mv "${f}" "${f//_/-}"; done
As for your third problem I'm sure it can be done too but maybe a more sophisticated approach than raw shell one-liners will help, as #tchrist mentioned.
My favorite solution is my own rename script. The simplest example that maps to your problems are these:
% rename 's/_/-/g' *
% rename 's/(\p{Lower})(\p{Upper})/$1 $2/g' *
Although I really hate whitespace in my filenames, especially vertical whitespace:
% rename 's/\s//g' *
% rename 's/\v//g' *
et cetera. It’s based on a script by The Larry Wall, but extended with options, as in:
usage: /home/tchrist/scripts/rename [-ifqI0vnml] [-F file] perlexpr [files]
-i ask about clobbering existent files
-f force clobbers without inquiring
-q quietly skip clobbers without inquiring
-I ask about all changes
-0 read null-terminated filenames
-v verbosely says what its doing
-V verbosely says what its doing but with newlines between old and new filenames
-n don't really do it
-m to always rename
-l to always symlink
-F path read filelist to change from magic path(s)
As you see, it can change not just the names of files, but where symbolic links are pointing to using the same pattern. You don’t have to use a s/// pattern, although often one does.
The other tools in that directory are mostly for Unicode work, of which there are some super-useful ones.
The above answers apply to Debian, Ubuntu etc
For RHEL and co: rename from_pattern to_pattern files
I think the link is broken and I couldn't find the page in the webarchive to the rename script in tchrist's post, so here is another one in Perl.
#!/usr/bin/perl
# -w switch is off bc HERE docs cause erroneous messages to be displayed under
# Cygwin
#From the Perl Cookbook, Ch. 9.9
# rename - Larry's filename fixer
$help = <<EOF;
Usage: rename expr [files]
This script's first argument is Perl code that alters the filename
(stored in \$_ ) to reflect how you want the file renamed. It can do
this because it uses an eval to do the hard work. It also skips rename
calls when the filename is untouched. This lets you simply use
wildcards like rename EXPR * instead of making long lists of filenames.
Here are five examples of calling the rename program from your shell:
% rename 's/\.orig$//' *.orig
% rename 'tr/A-Z/a-z/ unless /^Make/' *
% rename '$_ .= ".bad"' *.f
% rename 'print "$_: "; s/foo/bar/ if <STDIN> =~ /^y/i' *
% find /tmp -name '*~' -print | rename 's/^(.+)~$/.#$1/'
The first shell command removes a trailing ".orig" from each filename.
The second converts uppercase to lowercase. Because a translation is
used rather than the lc function, this conversion won't be locale-
aware. To fix that, you'd have to write:
% rename 'use locale; $_ = lc($_) unless /^Make/' *
The third appends ".bad" to each Fortran file ending in ".f", something
a lot of us have wanted to do for a long time.
The fourth prompts the user for the change. Each file's name is printed
to standard output and a response is read from standard input. If the
user types something starting with a "y" or "Y", any "foo" in the
filename is changed to "bar".
The fifth uses find to locate files in /tmp that end with a tilde. It
renames these so that instead of ending with a tilde, they start with
a dot and a pound sign. In effect, this switches between two common
conventions for backup files
EOF
$op = shift or die $help;
chomp(#ARGV = <STDIN>) unless #ARGV;
for (#ARGV) {
$was = $_;
eval $op;
die $# if $#;
rename($was,$_) unless $was eq $_;
}