In gnuplot, I type
gnuplot> set style data lines
Then I run few other lines:
gnuplot> plot "./data/traj1.dat" u 1:4, "" u 1:6, "" u 1:9, "" u 1:11, "" u 1:13, "" u 1:15
gnuplot> plot "./data/traj2.dat" u 1:4, "" u 1:6, "" u 1:9, "" u 1:11, "" u 1:13, "" u 1:15
gnuplot> plot "./data/traj3.dat" u 1:4, "" u 1:6, "" u 1:9, "" u 1:11, "" u 1:13, "" u 1:15
Now I want to change style. I start with
gnuplot> set
I want to press for example ctrl-r (http://www.bigsmoke.us/readline/shortcuts) and have the command be completed to
gnuplot> set style data lines
then I can change lines to points for example.
How do I make this auto-completion happen?
A partial solution is indeed to compile gnuplot with readline support. You mention that this is your last option in the comments, but I think that it is your only option if not you want to code a gnuplot frontend yourself. Maybe it helps to know that it is really easy to compile gnuplot from the ubuntu sources. I just did this myself in <10 min. Simply run (in a directory of your choice) the commands
sudo apt-get purge gnuplot
sudo apt-get build-dep gnuplot
cd `mktemp -d`
apt-get source gnuplot
cd gnuplot*
./configure --with-readline=gnu
make
sudo make install
Pressing the tab-key after writing the first few letters will complete the present word and if you press tab twice it will print a list of suggestions as you know it from your gnu-shell. Unfortunately not all readline features seem to work with the current gnuplot (I know they did once). E.g. Ctrl+r for reverse search (would be very useful for gnuplot) does not work for me. Hope this helps though admittedly this is possibly only a partial solution for you.
You can use rlwrap to get this functionality (history search with CTRL+R, filename and keyword completion) without compiling anything. If you use Ubuntu, install it from universe repositories by running:
sudo apt-get install rlwrap
Run gnuplot with:
rlwrap -a -N -c -b \' -D 2 -s 1000 gnuplot
where -a -N overrides gnuplot built-in readline support, -c gives you filename completion, -b \' lets you complete stuff like plot 'incomp[TAB]lete', -D 2 drops duplicates from history and -s 1000 increases the history size from the default 300.
Or add this line to your start-up script (i.e., .bashrc, .zshrc), so you can use gnuplot without any additional typing:
alias gnuplot="rlwrap -a -N -c -b \' -D 2 -s 1000 gnuplot"
Also, it is possible to have keyword completion by listing all keywords in a file $RLWRAP_HOME/gnuplot_completions. However, context-sensitive completion is impossible using rlwrap.
You may want to export your gnuplot command history to rlwrap (so you don't have to start from scratch), like this:
tail -n +2 ~/.gnuplot_history | while read -r; do print $REPLY; done > $RLWRAP_HOME/gnuplot_history
tail gets rid of gnuplot's header and print converts escaped characters (I wonder why gnuplot's history is stored like this).
Related
I have a folder full of jpg files which all end with "-x-large.jpg" I would like to rename them all using command line so that it gets rid of the -x-large and just becomes .jpg.
So for example 123-x-large.jpg will become 123.jpg
Can someone tell me how I can do this with the ren command?
Thanks.
for img in *-x-large.jpg; do mv -i -v "$img" "${img%-x-large.jpg}.jpg"; done
This loops on all matching images and moves them into a new file with a truncated name (removing -x-large.jpg from the end) with the .jpg added back to the end of the file name. I'm invoking this interactively with mv -i so you are prompted before overwriting each file. To force overwriting (always say "yes"), change that to mv (remove the -i). To prevent overwriting (always say "no"), change that to mv -n.
Remove the -v (verbose) if you don't want to see each rename happen.
If you have a very large number of these files, the command line will be too long for the above command (since *-x-large.jpg will be expanded onto a command line). You can work around that with find and xargs as follows:
sh <(find . -maxdepth 1 -name '*-x-large.jpg' \
|sed -r 's/(.*)(-x-large.jpg)$/mv -i "\1\2" "\1.jpg"/')
This creates a shell script using bash process substitution, using find to generate a list of all files we want to rename and then piping them through sed to create the mv commands.
(See above for the mv flags. I removed -v because presumably this will be a very long list.)
See the version below if you want to check the script before running it.
The above one-liner requires GNU bash or Korn shell (ksh) as well as GNU sed.
Here's how to do it with neither (in three commands):
find . -maxdepth 1 -name '*-x-large.jpg' \
|sed 's/.*/mv "&" "&/; s/-x-large.jpg$/.jpg"/' > temp.sh
sh temp.sh
rm temp.sh
Posix sed doesn't reliably support capture groups (\(…\) or sed -r to invoke ERE) and therefore we can't expect it to be able to match and recall text, so this version simply writes most of the command and then fixes the ending (the absence of a trailing double quotes in the first replacement is intentional; we add it in the second replacement). Posix shell (/bin/sh proper) doesn't support process substitution, so we dump to a temporary file, evaluate it, and then remove it.
If we're referring to Windows command-line, then SET /? is your friend. Loads of good info in there.
setlocal ENABLEDELAYEDEXPANSION
set SEARCH_SUFFIX=-x-large.jpg
set REPLACE_SUFFIX=.jpg
for %%A in ("*%SEARCH_SUFFIX%") do (
set OLD_NAME=%%~nxA
set NEW_NAME=!OLD_NAME:%SEARCH_SUFFIX%=%REPLACE_SUFFIX%!
ren "!OLD_NAME!" "!NEW_NAME!"
)
endlocal
I have some files: file1.txt, file2.txt and I would like to rename them like this: file1.something.txt and file2.something.txt
I looked for some similar questions and I come up with this:
for i in file*.txt; do echo mv $i file*.something.txt; done
but unfortunately the output is:
mv file1.txt file*.something.txt
mv file2.txt file*.something.txt
and therefore only 1 file is created.
Could please somebody help?
(I am using a macbook air, I am not sure if this is relevant)
Thank you very much
Try this :
rename -n 's/\.txt/something.txt' *
(remove -n switch when your tests are OK)
There are other tools with the same name which may or may not be able to do this, so be careful.
If you run the following command (GNU)
$ file "$(readlink -f "$(type -p rename)")"
and you have a result like
.../rename: Perl script, ASCII text executable
and not containing:
ELF
then this seems to be the right tool =)
If not, to make it the default (usually already the case) on Debian and derivative like Ubuntu :
$ sudo update-alternatives --set rename /path/to/rename
(replace /path/to/rename to the path of your perl's rename command.
If you don't have this command, search your package manager to install it or do it manually
Last but not least, this tool was originally written by Larry Wall, the Perl's dad.
How can I make aliases defined in ~/.config/fish/config.fish and functions defined in ~/.config/fish/functions available for the root user as well?
symlinking to /root/.config/fish didn't do the job. Furthermore, I'd also like to be able to use my functions and aliases via sudo, which is currently not working as well.
How do you guys do that?
I don't have a solution for the first problem (I don't have any functions that are useful for the root user), but the second one (functions not working as an argument for sudo) can be solved with a wrapper function:
function sudo
if functions -q $argv[1]
set argv fish -c "$argv"
end
command sudo $argv
end
The issue is of course that sudo is an external command (usually at /usr/bin/sudo) that cannot know about fish internals like function definitions. So this wrapper will call fish if you give it a function name. Of course, since this launches a new fish session, some things, like cd will not be useful because it won't alter the state of the main fish session.
I use a symlink to my config.fish and works perfectly. Have you checked the permissions?
777 lrwxrwxrwx 1 root root 35 Dez 21 2015 /root/.config/fish/config.fish -> /home/lara/.config/fish/config.fish
In newer versions you can also use the directory /etc/fish/ for system-wide configuration
The problem with sudo I solved with an alias:
# -E just preserv env. It's not really
# necessary, but may be useful.
function sudo; command sudo -sE $argv; end
from sudo man page:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's
password database entry. If a command is specified, it is passed to
the shell for execution via
the shell's -c option. If no command is specified, an interactive shell is executed.
Old question that I came across while attempting to do the same thing myself.
Neither existing solution from #faho or #LaraMaia solves the first part of the question, which is really what I needed for my use-case. Both solutions only handled functions that are defined in ~/.config/fish/functions. In-memory functions and aliases that have not been "saved" do not work.
So here's a version that does work for aliases/in-memory functions:
function sudo
if functions -q -- "$argv[1]"
set cmdline (
for arg in $argv
printf "\"%s\" " $arg
end
)
set -x function_src (string join "\n" (string escape --style=var (functions "$argv[1]")))
set argv fish -c 'string unescape --style=var (string split "\n" $function_src) | source; '$cmdline
command sudo -E $argv
else
command sudo $argv
end
end
Commented and slightly expanded version at this Gist.
I'm trying to do a find/replace and an insert with sed but I keep getting a message that says "extra characters at the end of n command." I'm also not running this from the terminal, it's embedded in a shell script so I can send it to others.
This is what I'm trying to run
sed -i 's/include "/var/run/racoon/*.conf" ;/# include "/var/run/racoon/*.conf" ;/g' ~/Documents/test.conf;
sed '$a; include "/etc/racoon/remote/*.conf" ;/g' ~/Documents/test.conf;
To make it easier to see, I'm trying to replace
include "/var/run/racoon/*.conf" ;
with
# include "/var/run/racoon/*.conf" ;
and then add this
include "/etc/racoon/remote/*.conf" ;
Basically, I just want to comment out the last line of a file and then insert a line after it. I'm pretty new to sed so I'm not sure if I'm going about this all wrong, any help will be appreciated!
There are at least 2 problems with what you're trying:
You need to use different delimiters since your pattern and replacement contain /. You can use |.
The * in the pattern needs to be escaped, \*.
As such, the first expression would look like:
sed -i 's|include "/var/run/racoon/\*.conf" ;|# include "/var/run/racoon/*.conf" ;|g' ~/Documents/test.conf;
Similarly, change the second one.
In case anybody runs into this problem, you either have to download gnu-sed or do it by other means.
You can download gnu-sed easily if you have Homebrew installed.
brew install gnu-sed
Or you can use perl and printf like I did
To do the replacement
sudo perl -pi -e 's|include "/var/run/racoon/\*.conf" ;|# include "/var/run/racoon/*.conf" ;|g' /etc/racoon/racoon.conf;
To add a line. It will always be line 139 for me so I could go this route.
line='include "/etc/racoon/remote/*.conf" ;'
sudo printf '%s\n' H 139i "$line" . wq | ed -s /etc/racoon/racoon.conf
Thank you to devnull for helping me get my syntax right.
Does sed -i work on AIX?
If not, how can I edit a file "in place" on AIX?
The -i option is a GNU (non-standard) extension to the sed command. It was not part of the classic interface to sed.
You can't edit in situ directly on AIX. You have to do the equivalent of:
sed 's/this/that/' infile > tmp.$$
mv tmp.$$ infile
You can only process one file at a time like this, whereas the -i option permits you to achieve the result for each of many files in its argument list. The -i option simply packages this sequence of events. It is undoubtedly useful, but it is not standard.
If you script this, you need to consider what happens if the command is interrupted; in particular, you do not want to leave temporary files around. This leads to something like:
tmp=tmp.$$ # Or an alternative mechanism for generating a temporary file name
for file in "$#"
do
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15
sed 's/this/that/' $file > $tmp
trap "" 0 1 2 3 13 15
mv $tmp $file
done
This removes the temporary file if a signal (HUP, INT, QUIT, PIPE or TERM) occurs while sed is running. Once the sed is complete, it ignores the signals while the mv occurs.
You can still enhance this by doing things such as creating the temporary file in the same directory as the source file, instead of potentially making the file in a wholly different file system.
The other enhancement is to allow the command (sed 's/this/that' in the example) to be specified on the command line. That gets trickier!
You could look up the overwrite (shell) command that Kernighan and Pike describe in their classic book 'The UNIX Programming Environment'.
#!/bin/ksh
host_name=$1
perl -pi -e "s/#workerid#/$host_name/g" test.conf
Above will replace #workerid# to $host_name inside test.conf
You can simply install GNU version of Unix commands on AIX :
http://www-03.ibm.com/systems/power/software/aix/linux/toolbox/alpha.html
You can use a here construction with vi:
vi file >/dev/null 2>&1 <<#
:1,$ s/old/new/g
:wq
#
When you want to do things in the vi-edit mode, you will need an ESC.
For an ESC press CTRL-V ESC.
When you use this in a non-interactive mode, vi can complain about the TERM not set. The solution is adding export TERM=vt100 before calling vi.
Another option is to use good old ed, like this:
ed fileToModify <<EOF
,s/^ff/gg/
w
q
EOF
you can use perl to do it :
perl -p -i.bak -e 's/old/new/g' test.txt
is going to create a .bak file.