Edit the contents of directory tables (Linux) - linux

How can I edit the contents of a directory file? Since directories are just special files with a table of links to the files contained within, I should be able to view the table right?
When I open a directory in vim I can't go into insert mode to edit the links, which I assumed would be the basic available functionality, even if it didn't work.

Like Kevin said, you can't do it. What you CAN do is see symlinks and hardlinks with find, and I suppose use the ln command to do what you want from there.
Using the find command
You can see all normal files with this command...
find <DIR> -type f -links 1
You can see hardlinked files with this command...
find <DIR> -type f -links +1
To see all symlinks, you could use...
find <DIR> -type l
You can add -ls to any of these to get a more verbose output.
Finding all symlinks in current directory, non-recursively, with additional file info:
find . -type l -maxdepth 1 -ls
Using ln and unlink commands
Use ln to create links...
ln <current_file> <link_filename>
...and for symlinks...
ln -s <current_file> <shortcut_filename>
..and of course to delete a hardlink, use rm as usual...
rm <hard_link_filename>
...and for deleting a symlink....
unlink <symlink_filename>
Note: if the symlink links to a directory, be sure not to include a final "/"
This will not work.... unlink /var/www/deleteme/ if deleteme is a directory on the other end.
Hope this helps.

Related

How to force "ln --symbolic" as --force does not work?

I am trying to do a ln -symbolyc link for all the .* files.
The problem is that it works first time, but second time it fails, and it looks that --force does not work
This is the code:
ln --symbolic --relative --force ./websites/web1es/.* ./websites/webtable/
This is the error:
ln: ./websites/webtable/.: cannot overwrite directory
ln: './websites/web1es/..' and './websites/webtable/..' are the same file
Does anyone have any idea?
Thanks a lot in advance for any clue!
When you specify .* in the shell, that includes . and ... If you specify a directory as the last argument, all the input files are linked into the destination directory with their same name as in the source directory.
As a result, your script is linking ./websites/web1es/.. to ./websites/webtable/... Unfortunately, the latter exists and is the parent directory of both directories, so deleting it is not possible. Moreover, as ln is telling you, the source and destination are the same file (or, in this case, directory), so even if ln could delete the destination, you'd experience data loss by doing so, so it's refusing.
Your solution should be to avoid handling . and ... For example, you could write this:
find ./websites/web1es -mindepth 1 -maxdepth 1 -name '.*' -print0 | \
xargs -0 -I {} ln -srf {} ./website/webtable
find does not enumerate . and .. here.

copying files from etc ending with digit to test1 directory

I'm new to linux and as an exercice I need to copy the "etc" files that end with a digit from home directory to the test1 directory
(with one command).
I tried this but it dosn't work
find /etc -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
this should work for your home directory files ending with digit
mv `ls . |grep -Eo "^.*[0-9]$"` your-directory
lets says in the current directory you have some files like ofjweifhwef9 or kfhiofeh8 ( files ending with digit)
so ls will list them.
this grep expression "^.*[0-9]$"` will find only files ending with digit. ( because in your home directory system wont allow to have a file like this "/etc/somefile123")
and then mv will move those files to your-directory
note :- if grep cannot find the files ending with number you will see an error ofcourse because mv needs 2 operands but since it wasn't there so error.
mv: missing destination file operand after './your-directory'
It is probably because /etc is a link in the system that you're using, and find doesn't seem to consider it a path until you add an extra / at the end. Try this instead:
find /etc/ -type f -iname "*[3-9]" -exec cp {} ../test1/ \;
Notice the /etc/ instead of /etc. I get the same behavior on my Mac where /etc is a link to another directory.
Of course, also make sure that you have files which names end on a digit under the /etc/ directory tree. I have none in my mac. You should get some files when you run:
find /etc/ -type f -iname "*[3-9]"
If you don't, you don't have any files to copy. You may also try: find /etc/ to see all files under the directory tree.
Finally, you may want to add the option: -depth 1 if you only want to copy the files in the /etc/ directory, as opposed to all the files that match in the directory tree under /etc/.

Copying folders but not tar files in linux

I have a folder, which consists of many folders and many tar files. (this many is around 1000)
I want to write a script to copy all folders with their contents to another directory, but I do not want to copy tar files.
I already know by writing
cp -a /source/ /path/
I can copy a directory with its contents to another, but for this case, I do not know how to do it.
As the number of directories are alot, I am not able to each time copy one directory.
I appreciate if someone can help me on this.
I think this might be what you're looking for.
You want to use the rsync command and in the --exclude flag you want to put *.tar
So your answer will look something like this:
rsync -r --exclude='*.tar' [source] [destination]
This is also a helpful little tutorial on how to use rsync.
You can combine cp in find to exclude *.tar files:
dest='/path/'
mkdir "$dest" &&
find /source -mindepth 1 -not -name '*.tar' -exec cp -a {} "$dest" \;

linux cp: how to have it follow links but not stop if a link target doesn't exist

I want to recursively copy a dir and have the targets of the links copied, but I do not want the cp to stop if a target of a link does not exist.
For example, I run this command:
cp -fprL /path/to/src_dir /path/to_dest_dir
But the first time it hits symlink where the target doesn't exist it exits:
cp: cannot stat `/path/to/non-existent/file': No such file or directory
Is there some way to get cp to silently skip these and continue on?
With the standard GNU toolchain, no, there's no way.
You could instead copy your files, keeping symlinks as symlinks, then use find -follow -type l -delete to delete the broken symlinks, and then copy again, this time following symlinks.
Of course, you could also just write a python etc. program to do the copy for you, or find all files in the original trees that are not broken symlinks and use these with cp, replacing parts of the path with the target path using sed:
find -type d|sed 's/^\(.*\)/"\1" "\/target\/\1"/g'|xargs -p mkdir
find -follow -not -type l -not -type d|sed 's/^\(.*\)/"\1" "\/target\/\1"/g'|xargs -n2 cp
sed will duplicate your found file path, prefixing it with the target directory.

Rsync make flat copy

I'm trying to write a script that copy all the files of one dir (with subdirs) to the root of another dir.
So Imagine I have this file structure:
/
pic.JPG
PIC5.JPG
FOLDER
pic2.JPG
pic3.JPG
FOLDER2
pic4.JPG
I want all the .JPG files from that directory and copy them over to another destination. But I don't want the directory structure, just the files.
This is what I've got:
"sudo rsync -aq --include '*/' --include '*.JPG' --exclude '*\' /source/picturesRoot/ /destination/flatView/
But it also copies the directories :(
I found this link on stackoverflow:
rsync : Recursively sync all files while ignoring the directory structure
I looked at the solution and didn't see much difference with my command, apart from the * and . in the path. I tried it but it didn't work.
I hope somebody can help me, thanks.
This answer cannot work for you because your pictures are not at the same level in directories. There is no option in rsync to skip the creation of directory structure. In the link you gave, it's working because the user explicitly select source files with *.
You can try something with find and rsync. Find will find files and rsync copy them.
Here is a solution :
find /source/picturesRoot -type f -name "*.JPG" -exec rsync -a {} /destination/flatView/ \;
Be careful, if two files have the same name just one will be in destination directory.

Resources