Sort files in dired by full path - emacs

I am using find-name-dired to find multiple instances of files that all have the same name (call it foo.txt) but in different directories. I want the files listed by alphabetical order of file path. However, they're listed in what looks like a random order. Neither dired-sort-menu nor dired-sort-chiesa will sort the output of find-name-dired, even though it will work on other dired buffers (whose format looks very similar). If I write the contents of the dired buffer to a file, I'm able to open a shell and submit the file to a sort command in the shell that uses the 9th field (the path) as a key. This produces output that looks right, but of course it's no longer a dired buffer.
Is there a way that I can
read in that externally sorted file and open it in dired "mode" (analogous to compilation mode),
sort the output of find-name-dired while still in dired mode, or
produce output from find-name-dired that's sorted the way I want from the beginning?
UPDATE:
Just to make things a bit more concrete, here's the current buffer:
/home/afrankel/Documents/emacs_test/:
find . \( -iname foo.txt \) -exec ls -ld \{\} \;
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 a/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 b/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 d/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 c/z/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 c/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 f/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 e/foo.txt
find finished at Fri Nov 30 17:00:41
Pressing "s" (which would sort most dired buffers) gives the error "Cannot sort this dired buffer".
I want the buffer to look like this:
/home/afrankel/Documents/emacs_test/:
find . \( -iname foo.txt \) -exec ls -ld \{\} \;
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 a/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 b/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 c/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 c/z/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 d/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 e/foo.txt
-rw-r--r-- 1 afrankel users 4 Nov 30 16:59 f/foo.txt
find finished at Fri Nov 30 17:00:41

When you type s in a "normal" Dired buffer, Dired doesn't actually sort the buffer. What it does is to change the value of dired-actual-switches so that it does (or doesn't) contain the -t option ("sort by modification time") and then call revert-buffer which re-runs ls with the new options. This obviously doesn't work in a Dired buffer produced by running find.
What you need to do instead is to arrange to run find with the -s option:
-s Cause find to traverse the file hierarchies in lexicographical
order, i.e., alphabetical order within each directory.
which you can do (for all find-dired commands) by evaluating
(setq find-program "find -s")

Okay, I figured out how to do it using defadvice to automatically change the value of find-ls-option while I'm executing my new wrapper function (find-name-dired-sorted) and then to change it back to its original value.
(defadvice find-name-dired (around find-name-dired-around)
"Advice: Sort output by path name."
(let ((find-ls-option (list "-exec ls -ld {} \\; |sort --key=9")))
ad-do-it))
(defun find-name-dired-sorted (dir pattern)
"Sort the output of find-name-dired by path name."
(interactive
"DFind-name (directory): \nsFind-name (filename wildcard): ")
(ad-activate 'find-name-dired)
(find-name-dired dir pattern)
(ad-deactivate 'find-name-dired))

Here's one way to do it manually via a temporary change to the configuration:
Run M-x customize-group find-dired.
Change the contents of the field "Find Ls Option" . It should initially read "-exec ls -ld {} \;". Append text to make it read "-exec ls -ld {} \; |sort --key=9". (In other words, sort by field 9, which is the full path treated as a single string.)
Set the option for the current session only.
UPDATE: It's better to do use defadvice, as I did in my other (later) answer.

Related

How to reset VSCode extensions for a workspace

I was having issues with a workspace so I tried disabling all of extensions for it. Then the only option was to enable all extensions for the workspace. I have extensions globally configured to be off or on, but I'm not sure how to get a workspace to reset to the global extensions now?
I know I can open a new window up and start manually enable/disabling the extensions in my workspace to match the new fresh window. The problem is that it would then have its own workspace extensions defined, so if I toggled one at a global level it would still have an override.
I also tried deleting the .vscode folder in the workspace, but that doesn't seem to change the extensions for the workspace.
It's not a great method but I guess this works with a lot of manual leg work.
Enable all extensions for workspace
Open a new VSCode window
Goto extensions and filter by #disabled
You can also do #enabled and disable all extensions in the first step if you have more disabled than enabled.
Now you have a list you can target. Just click Disable instead of Disable for Workspace.
I believe this should get your workspace back to normal. There has to be an easier way though. You may also have to toggle enabled extensions to disabled and then back to enabled in case it has a workspace override for them -- I didn't check how it would behave if a new window disabled the extension whether or not it would keep staying on.
I've found a way to reset all settings for a given workspace.
First, navigate to ~/.config/Code/User/workspaceStorage. Inside there, you'll find a lot of folders with seemingly random names. Each folder seems to represent one workspace.
# cd ~/.config/Code/User/workspaceStorage
# ls -la
total 156
drwxr-xr-x 39 micael micael 4096 Feb 18 15:00 .
drwxr-xr-x 6 micael micael 4096 Nov 15 13:05 ..
drwxr-xr-x 2 micael micael 4096 Jan 18 16:09 0cf549e23d37c32c70a7e30998ade1fe
drwxr-xr-x 3 micael micael 4096 Dec 29 17:42 1b637cb30f6c3acc9273df20c84be7aa
drwxr-xr-x 2 micael micael 4096 Jan 17 22:09 2010f3fb6dbb2574f12a5ba614b3b136
drwxr-xr-x 2 micael micael 4096 Feb 18 15:01 a09a9ab934662794ac48730fc950a654
...
Inside each folder, there's a workspace.json file that contains the path of the folder your workspace was created from.
We can use grep to quickly search all those folders for a matching string:
grep -r 'myfolder' ., where myfolder should be the name of the folder your workspace is using.
In this example, my workspace was created from a folder called python-playground:
# grep -r 'python-playground' .
./a09a9ab934662794ac48730fc950a654/workspace.json: "folder": "file:///home/micael/projects/python-playground"
grep: ./a09a9ab934662794ac48730fc950a654/state.vscdb: binary file matches
grep: ./a09a9ab934662794ac48730fc950a654/state.vscdb.backup: binary file matches
In my case, the folder I'm looking for is ./a09a9ab934662794ac48730fc950a654.
You'll likely get a few results, all inside the same folder. Let's first take a look inside the folder:
# ls -la a09a9ab934662794ac48730fc950a654
total 64
drwxr-xr-x 2 micael micael 4096 Feb 18 15:01 .
drwxr-xr-x 39 micael micael 4096 Feb 18 15:00 ..
-rw-r--r-- 1 micael micael 28672 Feb 18 15:01 state.vscdb
-rw-r--r-- 1 micael micael 24576 Feb 18 15:01 state.vscdb.backup
-rw-r--r-- 1 micael micael 64 Feb 18 15:00 workspace.json
# cat a09a9ab934662794ac48730fc950a654/workspace.json
{
"folder": "file:///home/micael/projects/python-playground"
}%
Now, we can either remove this folder or move it elsewhere. Make sure to close VSCode before doing so.
# rm -rf a09a9ab934662794ac48730fc950a654

Perl script that checks rotated log files

There is a web server running multiple websites with configured daily log files rotation.
Task: create a perl script that checks a list of current log files in source directory and compare it with a list of rotated log files in another dir. Script must print a name of log file, if one the yesterday's log was not rotated.
Source dir example:
ls -l /var/log/httpd/logs/*log
-rw-r--r-- 1 root root 0 May 20 00:01 /var/log/httpd/logs/access.log
-rw-r--r-- 1 root root 483652 May 20 12:54 /var/log/httpd/logs/othersite.com_80-access.log
-rw-r--r-- 1 root root 305 May 20 11:51 /var/log/httpd/logs/othersite.com_80-error.log
-rw-r--r-- 1 root root 0 May 20 00:01 /var/log/httpd/logs/error.log
-rw-r--r-- 1 root root 46222 May 20 12:45 /var/log/httpd/logs/www.site.com_8880-access.log
-rw-r--r-- 1 root root 0 May 20 00:01 /var/log/httpd/logs/www.site.com_8880-error.log
dir with a rotated logs:
ls -l /var/log/httpd/logs/completed/|grep 2014-05-19
-rw-r--r-- 1 root root 20 May 20 00:01 access.log.2014-05-19.gz
-rw-r--r-- 1 root root 107244 May 20 00:01 othersite.com_80-access.log.2014-05-19.gz
-rw-r--r-- 1 root root 9991 May 20 00:01 www.site.com_8880-access.log.2014-05-19.gz
-rw-r--r-- 1 root root 20 May 20 00:01 www.site.com_8880-error.log.2014-05-19.gz
In this case two yesterday's log files are absent\were not rotated:
-rw-r--r-- 1 root root 483652 May 20 12:54 /var/log/httpd/logs/othersite.com_80-access.log
-rw-r--r-- 1 root root 305 May 20 11:51 /var/log/httpd/logs/othersite.com_80-error.log
Looking forward to any suggestions!
Do a glob <> on the source directory and put in a hash key. You put the size of the log or date in the value of the hash. Then go to the destination directory and do the same thing - read the files and as you loop, check to see if you have the file in you hash. You can compare the size and date also. if you don't have it, copy it.

In Solaris server with Putty, unable to delete copied file with some irregular special character

I use putty to log in to a solaris server. while i was performing a copy operation I pressed left arrow key to edit the file name but it kept adding this character ^[[D desperate I pressed return key and the copy operation got complete
cp temp.jar temp.jar^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D
I was planning to rename is as temp.jar.test, I used 'ls' command to check what has happened and to my surprise two files came up with same name!
root[dev1]# ls -lt temp*
-rw-r--r-- 1 root other 488554 Apr 11 02:25 temp.jar
-rw-r--r-- 1 root other 488554 Apr 11 02:22 temp.jar
-rw-r--r-- 1 root other 488554 Apr 11 02:22 temp.jar.041114
-rw-r--r-- 1 root other 488487 Sep 30 2013 temp.jar.032514
and I used 'rm' command to delete, the original file got deleted but the file copied with ^[[D character is not getting deleted. And I'm getting a msg like 'eisvr.jar.: No such file or directory'
Help me delete the file. I tried issuing 'rm temp.jar^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D^[[D'. It resulted in more errors.
The simplest way would be to run this command:
rm -i temp.jar?????????*
and answer yes when prompted to remove the bogus one.

Perl: strange behaviour of glob with files greater than 2 GB

I'm simply trying to get a list of filenames given a path with wildcard.
my $path = "/foo/bar/*/*.txt";
my #file_list = glob($path);
foreach $current_file (#file_list) {
print "\n- $current_file";
}
Mostly this works perfectly, but if there's a file greater than 2GB, somewhere in one of the /foo/bar/* subpaths, the glob returns an empty array without any error or warning.
If I remove the file file or add a character/bracket sequence like this:
my $path = "/foo/bar/*[0-9]/*.txt";
or
my $path = "/foo/bar/*1/*.txt";
then the glob works again.
UPDATE:
Here's an example (for a matter of business policy I had to mask the pathname):
[root]/foo/bar # ls -lrt
drwxr-xr-x 2 root system 256 Oct 11 2006 lost+found
drwxr-xr-x 2 root system 256 Dec 27 2007 abc***
drwxr-xr-x 2 root system 256 Nov 12 15:32 cde***
-rw-r--r-- 1 root system 2734193149 Nov 15 05:07 archive1.tar.gz
-rw-r--r-- 1 root system 6913743 Nov 16 05:05 archive2.tar.gz
drwxr-xr-x 2 root system 256 Nov 16 10:00 fgh***
[root]/foo/bar # /home/user/test.pl
[root]/foo/bar #
Removing the >2GB file (or globbing with "/foo/bar/[acf]/" istead of "/foo/bar//")
[root]/foo/bar # ls -lrt
drwxr-xr-x 2 root system 256 Oct 11 2006 lost+found
drwxr-xr-x 2 root system 256 Dec 27 2007 abc***
drwxr-xr-x 2 root system 256 Nov 12 15:32 cde***
-rw-r--r-- 1 root system 6913743 Nov 16 05:05 archive2.tar.gz
drwxr-xr-x 2 root system 256 Nov 16 10:00 fgh***
[root]/foo/bar # /home/user/test.pl
- /foo/bar/abc***/heapdump.phd.gz
- /foo/bar/cde***/javacore.txt.gz
- /foo/bar/fgh***/stuff.txt
[root]/foo/bar #
Any suggestion?
I'm working with:
Perl 5.8.8
Aix 5.3
The filesystem is a local jfs.
In the absence of a proper answer you're going to want a work-around. I'm guessing you've hit some platform-specific bug in the glob() implementation of 5.8.8
I had a quick look at the source on CPAN but my C is too rusty to spot anything useful.
There have been lots of changes to that module though, so a bug may well have been reported and fixed. You're not even on the last release of 5.8 - there's a 5.8.9 out there which mentions updates to AIX compatibility and File::Glob.
I'd test this by installing local::lib if you haven't already and then perhaps cpanm and try updating File::Glob - see what that does. You might need to download the files by hand from e.g. here
If that solves the problem then you can either deploy updates to the required systems, or you'll have to re-implement the bits of glob() you want. Which is going to depend on how complex your patterns get.
If it doesn't solve the problem then at least you'll be able to stick some printf's into the code and see what it's doing.
Hopefully someone will post a real answer and make this redundant about 5 minutes after I click "Post Your Answer" though.
I've never used the new Glob function before, so i cant comment on benefits/problems, but it seems quite a lot of people have had issues using it: see => https://stackoverflow.com/search?q=perl+glob&submit=search for some questions and possible solutions.
IF you don't mind trying out something else:
Here is my tried and tested 'old school' perl solution i have used in countless projects:
my $path = "/foo/bar/";
my #result_array = qx(find $path -iname '*.txt'); #run the system find command
If you - for whatever reason prefer not to run a system command from within your script, then lookup the built in Find::Perl Module instead: http://search.cpan.org/~dom/perl-5.12.5/lib/File/Find.pm
good luck

GWT + eclipse, which files are part of my source?

i created a GWT project in eclipse, and it's time to put some code back into source control. i'm not sure at this point which files are generated and can be left out of source control,
a. under war/myapp/gwt/... i see many, many files related to the standard GWT themes.
b. under war/myapp,
-rw-r--r-- 1 10102022 1602597546 1876 Jan 24 16:41 0182DE3CC529E42DA72BBD969A44841E.gwt.rpc
-rw-r--r-- 1 10102022 1602597546 1456 Jan 24 14:09 4F701266A6E52E1E409583EA9AEC39E2.gwt.rpc
-rw-r--r-- 1 10102022 1602597546 1876 Jan 25 08:38 D98FD8FE56B70659E9608109BCF8B3C1.gwt.rpc
-rw-r--r-- 1 10102022 1602597546 43 Dec 16 16:01 clear.cache.gif
drwxr-xr-x 6 10102022 1602597546 204 Jan 25 08:26 gwt
-rw-r--r-- 1 10102022 1602597546 11289 Dec 17 01:33 hosted.html
-rw-r--r-- 1 10102022 1602597546 5232 Jan 25 08:31 photodrop_web_gwt.nocache.js
normally i'd just rely on eclipse build > clean to get rid of the build time artifacts. however, i did that, and i still see WEB-INF/classes full of class files, so i know that clean isn't working.
"war/myapp" is by default GWT's output directory. So as long as you haven't saved any files there manually (you shouldn't), you can delete that directory completely.
As always, make a backup first...
I'm using source control for GWT + GAE, and this ignore file has been working great:
syntax: regexp
^war/myapp$
syntax: regexp
^war/WEB-INF/appengine-generated/datastore-indexes-auto\.xml$
syntax: regexp
^war/WEB-INF/appengine-generated/local_db\.bin