UNIX Shell: List all files in directory excluding directory names - linux

I want to list all the files in a directory recursively. I am storing this output in a file that I will later iterate through and use each line as an argument in another command.
However all the commands I have tried have listed the directory name as one of the output lines followed by the files and directories contained in the directory.
I have tried the following:
tree -if --noreport . > files_names.txt
This has given me some success, but it still prints the directories. An example output is as follows:
/testdir
/testdir/rightfolder/
/testdir/rightfolder/file2.txt
/testdir/rightfolder/file3.txt
/testdir/wrongfolder/
/testdir/wrongfolder/file.txt
I have checked the man pages for tree and ls.
Is there a flag or another command that will give me the correct output. I have considered using a flag for tree to list the directories and then removing all those entries from the original list but this is not elegant at all.

You could use find(1) and filter by type:
find ./ -type f

Related

How to display full path of file using ls in linux with -R option in conjunction with grep

I'm trying to find a way to recursively look through a directory and display the full path of the files to the right of the files listed. For example, this is what happens when I search and list all files within the directory and subdirectories:
example here
With Grep, it simply shows the file name but not the full path, which I expected from the first picture. Is there anyway I can show the absolute path?
example here
I know adding -d option can provide this, but it only shows directories/files at that certain level of the directory and if I wanted to show all levels, I would have to keep track of how many levels there are within the directory and print each level one by one.
example here
If you use bash, you can use globstar to expand the paths from the start:
shopt -s globstar
ls -lhd path/**
Of course there's also
find path -ls

How do I copy differing content files from one directory to another?

There exists two directories: a/ and b/.
I'd like to copy all the files(recursively) from a/ into b/.
However, I only want to copy over an a file if its content is different than the already existing b file. If the corresponding b file does not exist, then you would still copy over the a file.
*by "corresponding file", I mean a files with the same name and relative path from their parent directories.
note:
The reason I don't want to overwrite a b file with the same exact contents, is because the b directory is being monitored by another program, and I don't want the file date to change causing the program to do more work than required.
I'm essentially looking for a way to perform a cp -rf a/ b/ while performing a diff check on each file. If the file's are different, perform the copy; otherwise skip the copy.
I see that cp has an update flag:
-u, --update
copy only when the SOURCE file is newer than the destination file or when the
destination file is missing
but this will not work because I'm not concerned about newer files; I'm concerned about different file contents.
Any shell language will do.
I've been attempting to get this to work by injecting my diff check into a find command:
find a/ ??? -exec cp {} b \;
This doesn't seem like an uncommon thing to do between two directories, so I'm hoping there is an elegant command line solution as aposed to me having to write a python script.
You can achieve this using rsync. Files or directories will be updated only if there is any new update in source folder.
$rsync -av --progress sourcefolder destinationfolder

The output of ls with -aF option is not clear

When I try the command ls with -aF option inside any directory whether it's empty or not, I always got the following:
./ ../
so what does the output mean when I have these two options together with ls command?
When you use ls, you are reading a directory file, not actually looking in a directory. Every directory listing contains an entry for the present/current directory, as well as its parent directory, just as you would expect to also see listings for sub/child directories in any directory listing.
The -A option for ls merely tells ls to display ALL files, which includes the entries of ./ & ../ for present and parent. Note that these dots are merely a shorthand that the shell (bash) uses to represent file paths for those files. In other words, what "./" really means is say ~/Desktop if you were currently in the Desktop directory doing an ls. And "../" would mean "~/" which is just another symbolic shorthand to represent your user home directory, which is probably something like /Users/your_username on macOS (OS X), or /usr/your_username for various Linux distributions. Note that those paths could also be written with the forward slash appended at the end and would mean the same thing (e.g., /Users/your_username/ is the same as /Users/your_username because they are both references to other directories (directory files).
Use the -a option for ls if you don't want to see ./ & ../, but still want to see (other) hidden files.
Using the -F option causes ls to display appended characters to the file types based on the file type. This is why directories are displayed with the forward slash appended at the end, and executables are displayed as executable* (with the asterisk appended), and regular files have no appendage (e.g., .txt, .png, .dmg).

Why do some linux commands work with a "*" in a list of files but others do not?

why does, for instance,
ls -1 /path/to/something/data*data/file*.txt
work fine, while something like the following returns an error:
tar -xzvf *tar.gz
tar: evsClient-v.0.0.6.tar.gz: Not found in archive
tar: evsClient-v.0.0.7.tar.gz: Not found in archive
The -f option to tar only expects one argument to specify the file to process. If using a glob expression as you have to tar -xzvf and there are multiple files that get expanded as a result, the files after the first one are taken to be regular arguments to tar, not an option argument to -f.
Since you are using -x, tar is in extraction mode, and it is taking the other files to be the name of files to be extracted from the archive that it is operating on.
When * isn't quoted, any word containing it is treated as a shell pattern, which expands to a list of file names matching that pattern.
In your first example, the pattern expands to a list of existing files, which ls then dutifully displays.
In your second example, the pattern again expands to a list of matching files. However, only the first member of that list is treated as the argument to the f option. The remaining items are names of files you want to extract from the first one, which is not what you intended.
The general rule is that the pattern simply provides a list of file names; it's up to you to ensure that the resulting list of files is a correct set of arguments for the command you are running.
The "*" is actually expanded by the shell and the resulting list of filenames are then presented as arguments to the command in question.
The "ls" command supports a list of file names and so does the "tar" command. But the signature of tar is:
tar option(s) archive_name file_name(s)
So - in your example I assume that the command line is expanded to:
tar -xzvf evsClient-v.0.0.5.tar.gz evsClient-v.0.0.6.tar.gz evsClient-v.0.0.7.tar.gz
giving you the error because the two latter archives cannot be extracted from the first.

Wget - output directory prefix

Currently I try to use:
"wget --user=xxx --password=xxx -r ftp://www.domain.com/htdocs/"
But this saves output files to current directory in this fashion:
curdir/www.domain.com/htdocs/*
I need it to be:
curdir/*
Is there a way to do this, I only see a way to use output prefix, but i think this will just allow me to define directory outside current dir?
You can combine --no-directories if you want all your files inside one directory or --no-host-directories to have subdirectories but no subdirectories per host with your --directory-prefix option.
2.6 Directory Options
‘-nd’
‘--no-directories’
Do not create a hierarchy of directories when retrieving recursively. With this option turned on, all files will get saved to the current directory, without clobbering (if a name shows up more than once, the filenames will get extensions ‘.n’).
‘-nH’
‘--no-host-directories’
Disable generation of host-prefixed directories. By default, invoking Wget with ‘-r http://fly.srk.fer.hr/’ will create a structure of directories beginning with fly.srk.fer.hr/. This option disables such behavior.
‘-P prefix’
‘--directory-prefix=prefix’
Set directory prefix to prefix. The directory prefix is the directory where all other files and subdirectories will be saved to, i.e. the top of the retrieval tree. The default is ‘.’ (the current directory).
(From the wget manual.)

Resources