How to tar all files in current directory using tar but without inputing names of tar file and all files? - unix

ENV:
macOS Sierra 10.12.6
Raw input(example):
.
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
0 directories, 6 files
In a test folder, there are 6 files.
Expected output:
.
├── all.tar
├── f1.md
├── f2.md
├── f3.md
├── f4.txt
├── f5.csv
└── f6.doc
0 directories, 7 files
Trying and Problem
tar -cvf all.tar f1.md f2.md f3.md f4.txt f5.csv f6.doc
Though I get the result from the above method but I have to inputing all file names and the compressed file name, which is inconvenient. For example , I can select all files and right click, then choose compressed option without inputing all.tar (I don't mind the .tar filenames.)
Hope
command-line method without inputing specific file names.

In case you want all files, including those in the subdirectories (or if you have no subdirectories), you would run:
tar -cvf all.tar *
Then, bash would expand * into the list of all files in the current directory, including subdirectories.
In case you want only those files in the current directory, but NOT in the subdirectories, then you would have to use find, in a more complicated command. Let me know if this is the case for you, and I can take the time to find that combination of commands for you.

Related

rsync include specific files and exclude directory

I have a directory structure as below:
base
├── config.yml
├── build
│ └── output.yml
│ └── <multiple level sub-directories each having many files including *.c and *.h files>
├── <source directories - having many sub-directories with various files including *.c and *.h files>
│ ├── <xyz>
| │ ├── <x1>
| │ .
│ | └── <xy>
│ .
│ .
│ └── <abc>
├── <more directories, each having multiple files including *.c and *.h files>
I need to sync this directory to remote, but I only need *.c and *.h files. Also complete 'build' directory needs to be excluded. I am running below command:
rsync -avm --include '*/' --include='*.c' --include='*.h' --exclude='*' base "$target_loc"
This is syncing all *.c and *.h files which is desired but it also syncs *.c and *.h files from build and its sub directories
I tried
rsync -avm --include '*/' --include='*.c' --include='*.h' --exclude='build' --exclude='*' base "$target_loc". It still syncs files from build and it's sub directories.
How can I fix this?
You need to put --exclude='build' before --include '*/'. Both of these rules could apply to the "build" directory, and whichever is given first takes precedence, so to get the --exclude rule to override the --include rule, you need to list it first.
From the rsync man page, in the FILTER RULES section (with my emphasis):
As the list of files/directories to transfer is built, rsync checks
each name to be transferred against the list of include/exclude
patterns in turn, and the first matching pattern is acted on: if it is
an exclude pattern, then that file is skipped; if it is an include
pattern then that filename is not skipped; if no matching pattern is
found, then the filename is not skipped.

How to compile multiple simple projects with GNU make

I am trying to implement various project from a programming book. My intention was to have each project exercise in its own folder and then have a makefile that compiles all of them with something like a make all. The folder structure is like this:
.
├── Makefile
├── bin
│   ├── prog1
│ ├── prog2
│ └── prog3
└── src
├── prog1
│ ├── Makefile
│ └── main.c
├── prog2
│ ├── Makefile
│ └── main.c
└── prog3
├── Makefile
└── main.c
I would like to learn how to set up such a structure. In particular the part where the top makefile visit all folders in src calls make there, and then copies and renames the executable into the bin folders.
Your layout schematic shows a makefile for each exercise, plus the top-level makefile that you seem actually to be asking about. It would be best for the top-level makefile to avoid duplicating the behavior of the per-exercise makefiles, as such duplication would create an additional maintenance burden for you. Additionally, it is likely that you will eventually progress to exercises involving multiple source files, and perhaps to some that have multiple artifacts to be built. This is all the more reason for each per-exercise makefile to contain everything necessary to build the exercise with which it is associated (into the exercise-specific directory), and for the top-level makefile to depend on those.
Following that scheme would leave a well-defined role for the top-level makefile: to perform the per-exercise builds (by recursively running make), and to copy the resulting binaries to bin/. This is not the only way to set up a system of cooperating makefiles, but it is fairly easy, and that will allow you to focus on the exercises instead of on the build system.
Let us suppose, then, that each individual exercise can be built by changing to its directory and running make, with the result being an executable in the same directory, with the same name as the directory. That is, from the top-level directory, executing cd src/prog2; make would produce the wanted executable as src/prog2/prog2. In that case, the top-level makefile needs little more than the names of all the exercises, and a couple of rules:
EXERCISES = prog1 prog2 prog3
BINARIES = $(EXERCISES:%=bin/%)
all: $(BINARIES)
$(BINARIES):
make -C src/$$(basename $#)
cp src/$$(basename $#)/$$(basename $#) $#
Note: that uses a feature specific to GNU's implementation of make to compute the names of the wanted binaries from the exercise names. I take that to be acceptable, since you tagged [gnu-make], but in any case, it is a convenience feature, not a necessity.
There are different ways to tackle this, but something like this should work for your example:
PROGS := bin/prog1 bin/prog2 bin/prog3
all: $(PROGS)
$(PROGS):
$(MAKE) -C src/$(#F)
mkdir -p $(#D)
cp src/$(#F)/main $#
.PHONY: clean
clean:
rm -f $(PROGS)
for t in $(PROGS); do make -C src/`basename $$t` clean; done
We define a list of targets (PROGS) we are to build. We say these targets are prerequisites of all and then we go ahead and define how they should be built, that is: we recursively descent into src/ plus filename part of the target to run make there. We create directory of the target to be sure it's there and copy main from the directory we've descended to the path of the target.
For a good measure, there is a clean target as well that removes all the PROGS and runs make clean recursively in src/.

zsh delete subdirectory with wildcard in path

For a directory structure of:
└── bar
├── first
│   └── tmp
└── second
└── tmp
I want to delete all tmp directories.
However,
rm -rf 'bar/*/tmp/'
does not delete the directory
ls bar/*/
still retrurns both tmp directories:
bar/first/:
tmp
bar/second/:
tmp
your problem here is the single quotes
rm -rf 'bar/*/tmp/'
if you remove them you'll be fine.
rm -rf bar/*/tmp
The reason for this is that single quotes in (most, if not all) shell languages indicates that the contained string of characters is to be treated entirely as a string, which ignores the globbing you are trying to do.

Is there a general convention for naming files and folders?

I'm working on a program that generates simple text files to save the state of users.
To keep things organized, I have a folder for users. Nested inside, I create a folder for each user with their ID, like this:
[Program Name]\currentusers\36a7781b
Inside of these folders I save a text file with the state of the user. At the moment I'm calling the file simply "appstate."
I have three questions:
Is there a convention for naming folders? E.g. currentusers, currentUsers, CurrentUsers, current_users.
Is there a convention for naming files? E.g. appstate, appState, AppState, app_state.
These are text files —should they include the .txt extension, or are they fine without it?
In order:
1) Yes, there is a convention to name folders. End the foldername with .d like foldername.d. This is used a lot in /etc/, but isn't too common to use. I never use it, and I barely see it except in old "things"
2) File basenames (that's the name of the file without an extension or path) are usually minorcase, and are often separated with - or _. There are no rules. Just avoid spaces or weird symbols. Keep it alphanumerical, for your own and others' sake.
3) POSIX doesn't understand extensions, but also doesn't care if you add them. Users do, and makes it easier for users (and editors/viewers) to know how to handle files.
You said your files are text files (and if it's raw text, end them with .txt), but I believe what you mean is that the files are not binary files (aka readable by a human). I believe your files have some sort of data structure that is parsed by your program, forming some sort of database with folders and users... thus your files are data files (ending with .dat as a convention).
So... all in all:
MyProgram/
├── anna
│   ├── birthday.dat
│   └── name.dat
├── dog
│   ├── birthday.dat
│   └── name.dat
├── john-smith
│   ├── birthday.dat
│   └── name.dat
├── mike
│   ├── birthday.dat
│   └── name.dat
└── rachel
├── birthday.dat
└── name.dat
5 directories, 10 files

R-Markdown's render_site function is deleting the contents of the .git folder

Im trying to version control a website generated with R-Markdown's render_site function by pushing it directly from the output directory, the default _site folder. Problem is, every time i call the render_site function it clears most of the content of the .git folder (save for the objects folder within) and breaks the link between the local and remote directory. Is there any way to stop this from happening? Curiously, the clean_site function clears the exact same folders and files from the .git folder so im guessing the problem is related to some post build cleanup.
The webpage directory looks something like this:
_site/
├── /.git
├── /index_files
├── /about_files
├── intex.html
├── about.html
└── styles.css
The .git folder before rendering the site looks like:
.git/
├── /hooks
├── /info
├── /logs
├── /objects
├── /refs
├── COMMIT_EDITMSG
├── config
├── description
├── FETCH_HEAD
├── HEAD
└── index
And after building only the objects folder is left:
.git/
└── /objects
I should also note that rendering each .Rmd file into htmls individually does not cause the same problem.
The default clean function for the site generator doesn't exclude anything. You can replace it fairly easily, using a scheme something like this:
Choose a name for your new generator, and put it in the YAML for the index.Rmd file, e.g.
site: my_site
Write my_site to modify the default generator (or the original custom one,
if you already had one):
my_site <- function(...) {
site <- rmarkdown:::default_site(...) # or bookdown::bookdown_site(...), etc.
# Modify the clean function
oldclean <- site$clean
site$clean <- function(...) {
files <- oldclean(...)
# leave out any filename containing .git
grep("[.]git", files, value = TRUE, invert = TRUE)
}
site
}
I haven't tested this and might have the pattern wrong in the new clean function, but it should be close to working.
You might also want to suggest to the rmarkdown authors (on their Github site) that it would be nice to have a way to mark certain files to exclude from cleaning.

Resources