I am trying to get "glob-expand-word" to work
pi#raspberrypi:~ $ cat .inputrc
set editing-mode vi
set keymap vi
set show-all-if-ambiguous on
Control-o: "> output"
pi#raspberrypi:~/tmp/test4 $ ls
total 8.0K
drwxr-xr-x 10 pi pi 4.0K Jan 27 08:48 ..
-rw-r--r-- 1 pi pi 0 Jan 27 08:48 3_eng
-rw-r--r-- 1 pi pi 0 Jan 27 08:48 2_eng
-rw-r--r-- 1 pi pi 0 Jan 27 08:48 1_eng
drwxr-xr-x 2 pi pi 4.0K Jan 27 08:48 .
pi#raspberrypi:~/tmp/test4 $ ls *eng^X
When trying to do the ctrlx, * (a two stroke combo) it doesn't work - instead of auto-completing and outputting "ls 1_eng 2_eng 3_eng" it instead appends ^X
What can I try next?
Try to bind ctrl-x :
bind '"\C-x": glob-list-expansions'
# Then -> ls *eng^X
Related
Is there any way to take away the owner's permission to read a file in macOS? I know there's no reason to do this but I have to for school and I can't find an answer anywhere. Removing my write permission works fine but when I try to remove my read permission it automatically give me my read and write permissions back. As you can see in the console when I use chmod -v -v (extra verbose) it shows the correct permissions it should be changed to but then when checking afterwards they havent changed into that...
thijs#Thijss-MacBook-Air-2 week6 % ls -l
total 16
-rw----r-- 1 thijs staff 12 Oct 11 21:10 greeting.txt
-rw-r--r-- 1 thijs staff 0 Oct 11 21:10 hello.txt
-rw------- 1 thijs staff 15 Oct 11 21:11 weather.txt
thijs#Thijss-MacBook-Air-2 week6 % chmod -v -v u-w weather.txt
weather.txt: 0100600 [-rw------- ] -> 0100400 [-r-------- ]
thijs#Thijss-MacBook-Air-2 week6 % ls -l
total 16
-rw----r-- 1 thijs staff 12 Oct 11 21:10 greeting.txt
-rw-r--r-- 1 thijs staff 0 Oct 11 21:10 hello.txt
-r-------- 1 thijs staff 15 Oct 11 21:11 weather.txt
thijs#Thijss-MacBook-Air-2 week6 % chmod -v -v u-r weather.txt
weather.txt: 0100400 [-r-------- ] -> 0100000 [---------- ]
thijs#Thijss-MacBook-Air-2 week6 % ls -l
total 16
-rw----r-- 1 thijs staff 12 Oct 11 21:10 greeting.txt
-rw-r--r-- 1 thijs staff 0 Oct 11 21:10 hello.txt
-rw------- 1 thijs staff 15 Oct 11 21:11 weather.txt
I have the following find command that searches all subdirectories and lists those folders that contain a *.RAR AND a *.MKV file.
find -type d -exec sh -c '[ -f "$0"/*.rar ] && [ -f "$0"/*.mkv ]' '{}' \; -print | sort
What I want to do now is to delete the *.MKV file from those directories.
For example, the above command finds FILEA.RAR and FILEB.MKV and lists the directory as DIRECTORY_CHARLIE. I would like to be able to have the above code, also delete the FILEB.MKV file, well delete the found MKV file from each directory that had both file types.
To start, I've created "_TestDir" with the following subfolders:
#useroneserver ~/files/_TestDir $ ls -all
drwxr-xr-x 2 userone userone 50 Feb 27 19:31 Folder01
drwxr-xr-x 2 userone userone 50 Feb 27 19:32 Folder02
drwxr-xr-x 2 userone userone 50 Feb 27 19:32 Folder03
drwxr-xr-x 2 userone userone 50 Feb 27 19:33 Folder04
drwxr-xr-x 2 userone userone 50 Feb 27 19:34 Folder05
Each folder has 2 files, except Folder03, which only has one file.
userone#remoteserver ~/files/_TestDir $ ls Folder01 -all
drwxr-xr-x 2 userone userone 50 Mar 1 20:03 .
drwxr-xr-x 7 userone userone 105 Feb 27 19:30 ..
-rw-r--r-- 1 userone userone 0 Feb 27 19:31 File1.rar
-rw-r--r-- 1 userone userone 0 Feb 27 19:30 FileA.mkv
userone#remoteserver ~/files/_TestDir $ ls Folder02 -all
drwxr-xr-x 2 userone userone 50 Mar 1 20:04 .
drwxr-xr-x 7 userone userone 105 Feb 27 19:30 ..
-rw-r--r-- 1 userone userone 0 Feb 27 19:32 File2.rar
-rw-r--r-- 1 userone userone 0 Feb 27 19:31 FileB.mkv
userone#remoteserver ~/files/_TestDir $ ls Folder03 -all
drwxr-xr-x 2 userone userone 30 Mar 1 20:04 .
drwxr-xr-x 7 userone userone 105 Feb 27 19:30 ..
-rw-r--r-- 1 userone userone 0 Feb 27 19:32 FileC.mkv
userone#remoteserver ~/files/_TestDir $ ls Folder04 -all
drwxr-xr-x 2 userone userone 50 Mar 1 20:04 .
drwxr-xr-x 7 userone userone 105 Feb 27 19:30 ..
-rw-r--r-- 1 userone userone 0 Feb 27 19:33 File4.rar
-rw-r--r-- 1 userone userone 0 Feb 27 19:33 FileD.mkv
userone#remoteserver ~/files/_TestDir $ ls Folder05 -all
drwxr-xr-x 2 userone userone 50 Mar 1 20:05 .
drwxr-xr-x 7 userone userone 105 Feb 27 19:30 ..
-rw-r--r-- 1 userone userone 0 Feb 27 19:34 File5.rar
-rw-r--r-- 1 userone userone 0 Feb 27 19:33 FileE.mkv
When I run the command in the original post, I get this:
userone#remoteserver ~/files/_TestDir $ find -type d -exec sh -c '[ -f "$0"/*.rar ] && [ -f "$0"/*.mkv ]' '{}' \; -print | sort
./Folder01
./Folder02
./Folder04
./Folder05
That is what I expect to see as the results, since folders 1, 2, 4 & 5 have a file of each of the extensions that I am looking for (*.rar & *.mkv), where as folder 3 only has one *.mkv file.
I have not tried to add any delete function since I have no clue where to start.
What I would like to happen is to be able to remove/delete the following
files:
FileA.mkv from Folder01
FileB.mkv from Folder02
FileD.mkv from Folder04
FileE.mkv from Folder05
Nothing gets deleted from Folder03 since it does not have a .RAR AND a .MKV file, it only has the .MKV. Hope this helps clarify.
Thank you for your assistance.
Regards.
You want to use xargs to run rm which will delete the files.
And define the replacement string, using the -I option of xargs.
Using your directory structure, you can do:
find -type d -exec sh -c '[ -f "$0"/*.rar ] && [ -f "$0"/*.mkv ]' '{}' \; -print | sort | xargs -I % sh -c "rm -f %/File?.mkv"
I took your exact find command, and added this:
| xargs -I % sh -c "rm -f %/File?.mkv"
Explanation
when find runs, it will output
./Folder01
./Folder02
./Folder04
./Folder05
Since xargs is used with the -I % option, it will run the command, replacing % with each directory (like in a loop, one by one). You could use another character than %, but avoid wildcard characters.
The command that xargs will run is sh -c "rm -f %/File?.mkv"
It will therefore do the following commands, in succession:
sh -c "rm -f Folder01/File?.mkv"
sh -c "rm -f Folder02/File?.mkv"
sh -c "rm -f Folder04/File?.mkv"
sh -c "rm -f Folder05/File?.mkv"
Obviously, you can adjust as required.
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 2 years ago.
Improve this question
I have an alias that I would like to be able to call into with exec but I'm not sure how to make it work. The example is simplified but I think enough to highlight the issue. Changing the alias to a function doesn't work either. Calling the alias/function directly does work, just not when using exec.
The command I am using is,
alias myalias="ls -lah /tmp"
exec myalias
But it fails with something similar to the following,
bash: exec: myalias: not found
Is it just not possible to do this using exec?
You don't have any functions or aliases in your example, but if you did have an alias, you could have aliased exec itself to exec it:
#!/bin/bash -i
# Define an alias
alias myalias="ls -lah /tmp"
# Allow `exec` to work for aliases
alias exec='exec '
# This now works as expected
exec myalias
Here's man bash for why this works:
Aliases allow a string to be substituted for a word when it is used as
the first word of a simple command. [...]
If the last character of the alias value is a blank, then the next command word following the alias is also checked for alias expansion.
An alias definition:
$ alias myalias='ls -lah /tmp'
Invoking the alias:
$ myalias
total 36M
drwxrwxrwt+ 1 myuser None 0 Nov 30 16:01 ./
drwxr-xr-x+ 1 myuser None 0 Nov 6 11:29 ../
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 a
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 b
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 c
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 d
-rw-r--r-- 1 myuser mygroup 36M Jun 6 17:29 giga.txt
drwx------+ 1 myuser mygroup 0 Mar 8 2020 runtime-makaakd/
drwx------+ 1 myuser mygroup 0 Nov 8 16:10 tmp.8yl3CJgSn2/
-rw------- 1 myuser mygroup 66 Oct 14 21:49 tmp.BeEvxDpHGr
... snip ...
As is (assigning string to a variable):
$ myalias="ls -lah /tmp"
'Running' the variable:
$ ${myalias}
total 36M
drwxrwxrwt+ 1 myuser None 0 Nov 30 16:01 ./
drwxr-xr-x+ 1 myuser None 0 Nov 6 11:29 ../
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 a
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 b
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 c
-rw-r--r-- 1 myuser mygroup 0 Oct 10 11:31 d
-rw-r--r-- 1 myuser mygroup 36M Jun 6 17:29 giga.txt
drwx------+ 1 myuser mygroup 0 Mar 8 2020 runtime-makaakd/
drwx------+ 1 myuser mygroup 0 Nov 8 16:10 tmp.8yl3CJgSn2/
-rw------- 1 myuser mygroup 66 Oct 14 21:49 tmp.BeEvxDpHGr
... snip ...
I am experimenting with TCL command exec in tclsh and here are my results:
% set show_me_dir "ls"
ls
% exec $show_me_dir
VboxSharedFolder
% set show_me_dir "ls -la"
ls -la
% exec $show_me_dir
couldn't execute "ls -la": no such file or directory
% set show_me_dir {ls -la}
ls -la
% exec $show_me_dir
couldn't execute "ls -la": no such file or directory
% ls -la
total 141
d---------+ 1 wakatana Domain Users 0 Jan 22 19:12 .
d---------+ 1 wakatana Domain Users 0 Apr 16 2014 ..
----------+ 1 wakatana Domain Users 20214 Jan 23 18:43 .bash_history
----------+ 1 wakatana Domain Users 1494 Apr 15 2014 .bash_profile
----------+ 1 wakatana Domain Users 7593 Jan 22 19:03 .bashrc
d---------+ 1 wakatana Domain Users 0 Jan 15 14:56 VboxSharedFolder
%
Can somebody please explain how can I execute command with arguments?
Edit:
The following example from Expanding a list of parameters in Tcl and eval article was big eye opener of what is going on here:
The variable $action is only expanded into the string "piemiddle apple" AFTER the command line has been split into its individual parameters:
% set action {piemiddle apple}
% set $action
can't read "piemiddle apple": no such variable
Result: set command "sees" one argument, equivalent to:
% set {piemiddle apple}
The expand operator allows you to specify that a variable is to be expanded BEFORE the command line is split into individual parameters:
% set action {piemiddle apple}
% set {*}$action
apple
Result: set command "sees" two arguments, equivalent to:
% set piemiddle apple
In earlier versions of Tcl, the eval command was the recommended alternative and it remains available today.
% set action {piemiddle apple}
% eval set $action
apple
Another examples which proves functionality of expansion operator:
% set {*}"name Linus"
Linus
% puts $name
Linus
%
%
% set distro Unbuntu
Unbuntu
% set {*}"linux $distro"
Unbuntu
% puts $linux
Unbuntu
%
%
Finally the discovery that exec needs command as it's first argument and first command option as it's second argument etc.
% exec "ls" "-la"
total 137
d---------+ 1 wakatana Domain Users 0 Jan 22 19:12 .
d---------+ 1 wakatana Domain Users 0 Apr 16 2014 ..
----------+ 1 wakatana Domain Users 20214 Jan 23 18:43 .bash_history
----------+ 1 wakatana Domain Users 1494 Apr 15 2014 .bash_profile
----------+ 1 wakatana Domain Users 7593 Jan 22 19:03 .bashrc
d---------+ 1 wakatana Domain Users 0 Jan 15 14:56 VboxSharedFolder
%
%
% exec "ls -la"
couldn't execute "ls -la": no such file or directory
The safest way to build a command for exec is to use Tcl's list. For example:
% set tcl_version
8.5
% set cmd [list ls -l tmp]
ls -l tmp
% eval exec $cmd
total 32
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 file.txt
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-1.dat
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-2.dat
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-3.dat
% exec {*}$cmd
total 32
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 file.txt
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-1.dat
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-2.dat
-rw-r--r-- 1 pynexj staff 1176 Jan 23 23:24 foo-3.dat
%
Note that {*} is a new syntax of Tcl 8.5 which can help reduce the uses of eval.
As example for ls command you can do:
exec {*}ls -lsa {*}[glob *.cpp]
Please have a look at What does {*} do in TCL?
I am having issues with this script/cron. I am running on a Raspberry pi and I have other cronjobs working just fine(so I know its not cron on the system).
My script:
#!/bin/bash
rm -f /var/www/output/*
This script is working just fine in the command line
bash clearcsv.sh
but when I try to turn it in to a cronjob, it seems that it is not executing
Cron script: */6 * * * * /home/pi/clearcsv.sh
This should erase the contents of the "output" folder every 6 minutes, but it does not. If someone could tell me where I am failing or point me in the right direction that would be great
Thanks
total 160
drwxrwxrwx 14 pi pi 4096 Mar 13 16:41 .
drwxr-xr-x 3 root root 4096 Dec 31 1969 ..
-rw-r--r-- 1 pi pi 0 Mar 10 21:56 ?
-rwxrwxrwx 1 pi pi 8700 Mar 13 15:32 .bash_history
-rwxrwxrwx 1 pi pi 220 Jan 7 16:10 .bash_logout
-rwxrwxrwx 1 pi pi 3243 Jan 7 16:10 .bashrc
drwxrwxrwx 8 pi pi 4096 Mar 10 19:24 .cache
-rwxrwxrwx 1 pi pi 41 Mar 13 16:11 clearcsv.sh
drwxrwxrwx 12 pi pi 4096 Feb 12 18:21 .config
-rwxrwxrwx 1 pi pi 420 Mar 13 17:02 csv.sh
drwxrwxrwx 2 pi pi 4096 Feb 12 18:20 Desktop
-rw-r--r-- 1 pi pi 35 Mar 7 08:17 .dmrc
drwxrwxrwx 2 pi pi 4096 Jan 16 13:32 .fontconfig
drwxrwxrwx 2 pi indiecity 4096 Jan 16 13:34 .gstreamer-0.10
drwxrwxrwx 2 pi pi 4096 Jan 16 13:32 .gvfs
drwxrwxrwx 3 pi pi 4096 Jan 16 13:33 indiecity
drwxrwxrwx 2 pi pi 4096 Mar 13 13:27 input
drwxrwxrwx 3 pi pi 4096 Jan 16 13:33 .local
drwxrwxrwx 9 pi pi 4096 Jan 16 14:30 .Mathematica
-rwxrwxrwx 1 pi pi 5781 Feb 3 2013 ocr_pi.png
-rwxrwxrwx 1 pi pi 0 Mar 10 18:24 output.csv
-rwxrwxrwx 1 pi pi 671 Mar 13 13:39 poller.sh
-rwxrwxrwx 1 pi pi 117 Feb 19 17:34 poll.sh
-rwxrwxrwx 1 pi pi 675 Jan 7 16:10 .profile
-rw-r--r-- 1 root root 3 Jan 16 14:09 restart
drwx------ 4 pi pi 4096 Mar 13 13:22 .thumbnails
-rwxrwxrwx 1 pi pi 56 Mar 7 08:17 .Xauthority
-rw------- 1 pi pi 17227 Mar 13 16:56 .xsession-errors
-rwxrwxrwx 1 pi pi 2385 Mar 6 19:06 .xsession-errors.old
Thank you all for your help. I have everything working now! Here is the code if you are interested
New Script used:
#!/bin/bash
/bin/rm -f /var/www/output/*
Cron
*/6 * * * * cd /home/pi && bash clearcsv.sh