Tar Directory Contents Without Creating A Root Folder In Archive - bash

I am running the following snippet in a bash script in a folder. This creates an archive where there is no root folder since I am running the script within the folder whose contents I am archiving.
tar -pczf $ARCHIVE_NAME --exclude=${ARCHIVE_NAME} --exclude=$(basename ${0}) *
Archive Contents:
/a/
/b/
/c/
/a_normal_file
works great, but since I am using the * it is not archiving hidden files in the immediate directory. I did some searching and found archiving (ubuntu tar) hidden directories I have then changed it to:
tar -pczf $ARCHIVE_NAME --exclude=${ARCHIVE_NAME} --exclude=$(basename ${0}) .
Archive Contents:
/./a/
/./b/
/./c/
/./.a_hidden_file
/./a_normal_file
still works, but now there is a root folder being created with the name being the '.' character. The contents are then within that. How do I get my previous result, but where it still archives hidden files in the immediate directory?
Thanks in advance!

Use -C, --directory DIR
--directory=$(dirname ${0})
Example:
$ ls -a xxx
. .. aaa .bbb
$ tar cvf test.tar --exclude test.tar -C xxx .
./
./.bbb
./aaa

While it doesn't affect the unpacking of the archive (since . just refers to the same dir), if it bothers you, you can change the wildcard from * to .[^.]* * to include all the hidden files as well.
In addition, if you have hidden files beginning with .., such as ..a, you'll need to add ..?* to the list as well.

Related

Copy whole directory but exclude all folders and subfolders with certain name

I'm not allowed to use rsync on the cluster I'm working on so I need to use cp. I want to copy a large directory including all files and subfolders etc. but without any folders that have the name "outdir".
I tried cp -r -v ./!(outdir) ../target-directory/
but it still copies all folders and contents in deeper directories with the name outdir. It only included the outdir folders in the highest directory.
I also tried cp -r ./*/!(outdir) ../target-directory/ but that one copied all files into the folder without keeping any hirarchy or folders etc.
I also tried certain find commands but it didn't work, but maybe I was just doing something stupid. I'm a beginner with bash so if you could explain your answer and what the flags etc. do that would really be helpfull, I've been trying forever now, on what I think shouldn't be that hard to do.
Instead of cp, you can use tar with option --exclude to control what you want copied or not.
The full command is:
tar --exclude="outdir" -cvpf - . | (cd TARGET_DIRECTORY; tar -xpf -)
So any path that contains the "outdir" pattern will be excluded.
Without the --exclude option, it will copy the entire structure of your current directory under TARGET_DIRECTORY.
You can replace the . in the first tar by your desired source directory.

Output A tar archive into a specific path in a bash script

I have a part in my script that uses tar to archive some folders. It should output the archived result to a specified folder.
The following tar command outputs the file to the right folder but makes the resulted archive nested with the full path leading to it.
e.g.
Inside my tar file I have the following folders:
full/path/to/file
The folder structure shouldn't look like that it should be relative to the parent folder not the root folder.
Here is the code:
...
local PROJECTS=(~/path/to/folder/*)
...
local PROJECT_PATH="${PROJECTS[$i]}"
local BACKUP_NAME=`date +%d%b%y`.tar.gz
echo Making folder "${PROJECT_PATH}"/backups
tar -czvf $PROJECT_PATH/backups/$BACKUP_NAME $PROJECT_PATH --exclude="${PROJECT_PATH}"/node_modules --exclude="${PROJECT_PATH}"/backups
If you want tar to save paths relative to some directory, use -C to change to that directory and provide relative paths:
tar -czvf "$PROJECT_PATH/backups/$BACKUP_NAME" -C "$PROJECT_PATH" . --exclude=./node_modules --exclude=./backups
-C "$PROJECT_PATH" tells tar to change to the $PROJECT_PATH directory, and the following . tells it to archive its current directory.

Copy command in Mac Terminal fails with "No such file or directory"

This should be straightforward, but I'm getting weird results.
I have a folder with subfolders containing ~4000 files. I'm trying to copy just the files of a certain filetype to another folder, while preserving the subfolder hierarchy.
Command:
cp -R /Users/Steve/Desktop/Hardscapes/*.LOB /Users/Steve/Desktop/Temp
fails with the message:
"/Users/Steve/Desktop/Hardscapes/*.LOB: No such file or directory".
I created the command by typing cp -R then dragging the source folder to the terminal window, adding *.LOB after the /, and dragging the destination folder to the terminal window.
Troubleshooting:
replacing *.LOB with *.* gives the same error.
cp -R /Users/Steve/Desktop/Hardscapes/ /Users/Steve/Desktop/Temp copies the entire Hardscapes folder to Temp, with all its subfolders and files.
Thanks for your help and suggestions.
EDIT: The folder Hardscapes contains only other folders. If I run the command above using one of those folders as the source, the contents are copied faithfully. The folder Hardscapes itself contains no .LOB files - they're only in the subfolders.
So maybe that's the issue, cp can't find any files corresponding to Hardscapes/*.LOB? But I thought the -R switch was supposed to tell it to look through all the subfolders.
Next I put a file named Test.LOB in the Hardscapes folder. The command above copies only that file and none of the subfolders. It looks like the -R switch is not doing its job. Do I have the syntax right?
Try this:
rsync -a --prune-empty-dirs --include '*/' --include '*.LOB' --exclude '*' /Users/Steve/Desktop/Hardscapes/ /Users/Steve/Desktop/Temp
As you already mentioned, directory Hardscapes itself contains no .LOB files. That's why your mask /Users/Steve/Desktop/Hardscapes/*.LOB results in matching no files at all.

Shell command to copy just html files to the correct folder

I'm creating a build script using npm.
The build script includes typescript compiling.
The typescript compiling copies the folder structure from a ts folder to a dist/js folder.
The ts folder is like
ts
-- one
-- one.html
-- one.ts
two
-- two.html
-- two.ts
And the dist/js folder created is like
js
-- one
-- one.js
two
-- two.js
The ts folders always contain html that I need to copy to the js after the compiling has run.
What shell command can I use to copy the html from the ts folder to the correct folder in the outputed js folder.
Update
I have tried the following command
"build:copy-html": "find ./app/ts -name '*.html' cp ./dist/js \\;",
but get an error of
find: cp: unknown primary or operator
UPDATE
In the ts folder I have
ts
--home
--home.html
--home.ts
I need the js folder to be
js
--home
--home.html
--home.js
I usually do the following:
(cd app/ts; tar -cf - `find . -name '*.html' `) | (cd app/dist/js ; tar -xf -)
I suppose that you want to copy all the '*.html' files from app/ts to app/js directory keeping the directory structure and there are no spaces in the file names.
There are some more methods. find and cpio combination usually appears in the manual page of find like here: https://linux.die.net/man/1/find

How to delete the files present in a directory

I have a folder in my directory called input_files which contains the list of input files. I am trying to delete the contents of this folder using the below command but getting I'm getting an error.
find /u/users/kisri1/scripts/design_matrix/input_files* -type f -delete
Error:
/u/users/kisri1/scripts/design_matrix/input_files: Is a directory
Please help to solve this thing. I want to write a shell script which can access the folder and delete the files.
rm is perfect in your case.
rm -rf /u/users/kisri1/scripts/design_matrix/input_files/* would do the trick and delete all files in your input_files directory without discrimination.
use the lines:
cd /u/users/kisri1/scripts/design_matrix/input_files
rm *
this will delete all files in the directory

Resources