Include only specific file patterns in meld comparison - filtering

I want to compare directories with Meld, but only specific file patterns.
E.g., only *.c;*.cc;*.icc;*.h files.
Meld can use File Filters, but I could only use them for exclusion filtering specific file patterns. That approach is not useful for me, I guess.
Can an inclusion filter be applied?
I tried with the idea of "double negation": Excluding "everything but *.c;*.cc;*.icc;*.h", which in effect would include only those patterns.
I tried using File Filters which worked well for listing "everything but ..." using ls -d -- <my_filter> at the command line (see this). I assume this is a necessary (but not sufficient) condition for any filter to work in Meld.
None of these worked:
!(*.c|*.h|*.cc)
!(*#(.c|.h|.cc))
!(*.#(c|h|cc))
Note: I do not mean to use any type of Text Filter, since I do not care at this point about the contents of files, but only about the file names.
Note : I have bash and
$ shopt extglob
extglob on

Related

Merge two PO files and overwrite matching translation rules

I'm attempting to merge two PO files.
I have a base.po file that has general translations.
I have an extra.po which has extra translations that I'd like to add to the base file OR overwrite translations for if there are matching translation IDs.
I've tried using msgmerge:
$ msgmerge extra.po base.po -o merge.po
But this comments out any translations with matching IDs.
Looking at the msgmerge documentation, it doesn't look like there is any option to effect this behavior.
I'd like to be able to have multiple extra translation files (extra1.po, extra2.po, etc.) so I can merge them with the base translation file and use them in different contexts.
Does anyone know how to do what I'm attempting?
Turns out I needed to be using msgcat instead.
The below command creates a PO file merge.po that contains all of the translations from extra.po and adds any additional translations from base.po.
The --use-first option specifies that if there is a matching translation id between the two files, to choose the translation from extra.po.
$ msgcat extra.po base.po -o merge.po --use-first

vifm search files in subfolders

How can I search files just like with / command but recursively scanning subfolders?
Or maybe there are other approaches to get a list of files that match some pattern in the current folder including all subfolders.
:find command
There is :fin[d] command for that. Internally it invokes find utility (this is configurable via 'findprg' option), so you can do everything find is capable of. That said, in most cases the simple form of the command suffices:
:find *.sh
Note that by default argument is treated as regular file pattern (-name option of find), which is different from regular expressions accepted by /. For searching via regexp, use:
:find -regex '.*_.*'
If you want to scan only specific subfolders, just select them before running the command and search will be limited only to those directories.
:find command brings up a menu with search results. If you want to process them like regular files (e.g. delete, copy, move), hit b to change list representation.
Alternative that uses /
Alternatively you can populate current view with list of files in all subdirectories with command like (see %u):
:!find%u
and then use /, although this might be less efficient.

How to join two files in Linux for example if i have many files

I have 133 files named as Trace1.log Trace2.log and so on so how can I merge all these files together and save it in one
To simply concatenate the files in alphabetical order,
cat Trace*.log >combined
Take care to name the destination file so it doesn't match the wildcard, or you will get weird results.
Alphabetical order means Trace10.log sorts before Trace2.log. If you need them in numeric order, use a more suitable naming convention (e.g. rename Trace1.log to Trace001.log, etc) or use multiple wildcards;
cat Trace?.log Trace??.log Trace???.log >combined
The locale will affect what exactly "alphabetic order" means; these guidelines apply to the traditional C locale and English-language locales at least (and most other Western languages).
You can try using the cat command.
$ cat Trace* > TraceFull.log
Take a look at this site Joining files together
if you're on a unix based system use the following command:
cat Trace*.log > TraceMerged.log
(while in the directory holding the logs)

What's the best way to perform a differential between a list of directories?

I am interested in looking at a list of directories and comparing the previous list with a current list of directories and setting up a script to do so. Maybe in perl or as a shell script.
Should I use something like diff? Programatically, what would be an ideal way to do this? For example let say I output the diff to an output file, if there is no diff then exit, if there is results, I want to see it.
Let's for example I have the following directories today:
/foo/bar/staging/abc
/foo/bar/staging/def
/foo/bar/staging/a1b2c3
Next day would look like this where a directory is either added, or renamed:
/foo/bar/staging/abc
/foo/bar/staging/def
/foo/bar/staging/ghi
/foo/bar/staging/a1b2c4
There might be better ways, but the way I typically do something like this is to run a find command in each directory root, and pipe the output to separate files. You can then diff the files using the diff tool of your choice. If you want to filter out certain directories or files, you can throw in some grep or grep -v commands in the pipeline, or you can experiment with options on the find command.
The other main option is to find a diff tool that offers directory/folder comparisons. Most of the goods ones support this, but I like the command line method, because you get more control over what you're diffing.
cd /my/directory/one
find . -print | sort > /temp/one.txt
cd /my/directory/two
find . -print | sort > /temp/two.txt
diff /temp/one.txt /temp/two.txt
also check the inotifywait command. it allows you to monitor files in RT.
You might also consider the find command using the -newer switch.
The usage is:
find . -newer timefile.txt -print
The -newer switch makes find return a list of files that are created or updated after the specified file's modification time. In the example above, any file created or updated after timefile.txt would be returned. You'd have to create a timefile.txt file, most likely once per day. Some versions of find have variations of newer that compare against other time stamps for a file (last modified, last accessed, last created, etc.)
This technique would not report a file that was deleted, however. A daily diff of the file listings could report that.

Difference in the paths in .gitignore file?

I've been using git but still having confusion about the .gitignore file paths.
So, what is the difference between the following two paths in .gitignore file?
tmp/*
public/documents/**/*
I can understand that tmp/* will ignore all the files and folders inside it. Am I right?
But what does that second line path mean?
This depends on the behavior of your shell. Git doesn't do any work to determine how to expand these. In general, * matches any single file or folder:
/a/*/z
matches /a/b/z
matches /a/c/z
doesn't match /a/b/c/z
** matches any string of folders:
/a/**/z
matches /a/b/z
matches /a/b/c/z
matches /a/b/c/d/e/f/g/h/i/z
doesn't match /a/b/c/z/d.pr0n
Combine ** with * to match files in an entire folder tree:
/a/**/z/*.pr0n
matches /a/b/c/z/d.pr0n
matches /a/b/z/foo.pr0n
doesn't match /a/b/z/bar.txt
Update (08-Mar-2016)
Today, I am unable to find a machine where ** does not work as claimed. That includes OSX-10.11.3 (El Capitan) and Ubuntu-14.04.1 (Trusty). Possibly git-ignore as been updated, or possibly recent fnmatch handles ** as people expect. So the accepted answer now seems to be correct in practice.
Original post
The ** has no special meaning in git. It is a feature of bash >= 4.0, via
shopt -s globstar
But git does not use bash. To see what git actually does, you can experiment with git add -nv and files in several levels of sub-directories.
For the OP, I've tried every combination I can think of for the .gitignore file, and nothing works any better than this:
public/documents/
The following does not do what everyone seems to think:
public/documents/**/*.obj
I cannot get that to work no matter what I try, but at least that is consistent with the git docs. I suspect that when people add that to .gitignore, it works by accident, only because their .obj files are precisely one sub-directory deep. They probably copied the double-asterisk from a bash script. But perhaps there are systems where fnmatch(3) can handle the double-asterisk as bash can.
If you're using a shell such as Bash 4, then ** is essentially a recursive version of *, which will match any number of subdirectories.
This makes more sense if you add a file extension to your examples. To match log files immediately inside tmp, you would type:
/tmp/*.log
To match log files anywhere in any subdirectory of tmp, you would type:
/tmp/**/*.log
But testing with git version 1.6.0.4 and bash version 3.2.17(1)-release, it appears that git does not support ** globs at all. The most recent man page for gitignore doesn't mention **, either, so this is either (1) very new, (2) unsupported, or (3) somehow dependent on your system's implementation of globbing.
Also, there's something subtle going on in your examples. This expression:
tmp/*
...actually means "ignore any file inside a tmp directory, anywhere in the source tree, but don't ignore the tmp directories themselves". Under normal circumstances, you'd probably just write:
/tmp
...which would ignore a single top-level tmp directory. If you do need to keep the tmp directories around, while ignoring their contents, you should place an empty .gitignore file in each tmp directory to make sure that git actually creates the directory.
Note that the '**', when combined with a sub-directory (**/bar), must have changed from its default behavior, since the release note for git1.8.2 now mentions:
The patterns in .gitignore and .gitattributes files can have **/, as a pattern that matches 0 or more levels of subdirectory.
E.g. "foo/**/bar" matches "bar" in "foo" itself or in a subdirectory of "foo".
See commit 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4:
"foo/**/bar" matches "foo/x/bar", "foo/x/y/bar"... but not "foo/bar".
We make a special case, when foo/**/ is detected (and "foo/" part is already matched), try matching "bar" with the rest of the string.
"Match one or more directories" semantics can be easily achieved using "foo/*/**/bar".
This also makes "**/foo" match "foo" in addition to "x/foo", "x/y/foo"..
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds#gmail.com>
Simon Buchan also commented:
current docs (.gitignore man page) are pretty clear that no subdirectory is needed, x/** matches all files under (possibly empty) x
The .gitignore man page does mention:
A trailing "/**" matches everything inside. For example, "abc/**" matches all files inside directory "abc", relative to the location of the .gitignore file, with infinite depth.
A slash followed by two consecutive asterisks then a slash matches zero or more directories. For example, "a/**/b" matches "a/b", "a/x/b", "a/x/y/b" and so on.
When ** isn't supported, the "/" is essentially a terminating character for the wildcard, so when you have something like:
public/documents/**/*
it is essentially looking for two wildcard items in between the slashes and does not pick up the slashes themselves. Consequently, this would be the same as:
public/documents/*/*
It doesn't work for me but you could create a new .gitignore in that subdirectory:
tmp/**/*.log
can be replaced by a .gitignore in tmp:
*.log