Change to xth directory terminal - unix

Is there a way in a unix shell (specifically Ubuntu) to change directory into the xth directory that was printed from the ls command?
I know you can sort a directory in multiple ways, but using the output from ls to get the xth directory?
An example shell:
$ ls
$ first_dir second_dir third_really_long_and_complex_dir
where I want to move into the third_really_long_and_complex_dir by passing 3 (or 2 in proper array format).
I know I could simply copy and paste, but if I'm already using the keyboard, it would be easier to type something like "cdls 2" or something like that if I knew the index.

The main problem with cd in an interactive session is that you generally want to change the current directory of the shell that is processing the command prompt. That means that launching a sub-shell (e.g. a script) would not help, since any cd calls would not affect the parent shell.
Depending on which shell you are using, however, you might be able to define a function to do this. For example in bash:
function cdls() {
# Save the current state of the nullglob option
SHOPT=`shopt -p nullglob`
# Make sure that */ expands to nothing when no directories are present
shopt -s nullglob
# Get a list of directories
DIRS=(*/)
# Restore the nullblob option state
$SHOPT
# cd using a zero-based index
cd "${DIRS[$1]}"
}
Note that in this example I absolutely refuse to parse the output of ls, for a number of reasons. Instead I let the shell itself retrieve a list of directories (or links to directories)...
That said, I suspect that using this function (or anything to this effect) is a very good way to set yourself up for an enormous mess - like using rm after changing to the wrong directory. File-name auto-completion is dangerous enough already, without forcing yourself to count...

Related

How to list contents of another directory without being in it?

Here is what my directory looks like:
Test ----
|
|----One
|
|----Two
I am attempting to list the contents of Two while still being in One and I am not able to do so.
I have tried this command (as seen in a other post) : "ls Test/" and it says No such file or directory. I have also tried ls Test/Two/ and it still does not work.
If you are in One and you want to list the contents of Two, you should go up to the parent directory using ..:
ls ../Two
../ will place you in the Test directory, from there, you can go to Two with no problem. If you have more depth levels, just add more ../ to go up one directory each time, but mind which is your current directory when running the command.
what does this command provide you in terminal.
ls -al Test //a flag is used for hidden file

Complex command execution in Makefile

I have a query regarding the execution of a complex command in the makefile of the current system.
I am currently using shell command in the makefile to execute the command. However my command fails as it is a combination of a many commands and execution collects a huge amount of data. The makefile content is something like this:
variable=$(shell ls -lart | grep name | cut -d/ -f2- )
However the make execution fails with execvp failure, since the file listing is huge and I need to parse all of them.
Please suggest me any ways to overcome this issue. Basically I would like to execute a complex command and assign that output to a makefile variable which I want to use later in the program.
(This may take a few iterations.)
This looks like a limitation of the architecture, not a Make limitation. There are several ways to address it, but you must show us how you use variable, otherwise even if you succeed in constructing it, you might not be able to use it as you intend. Please show us the exact operations you intend to perform on variable.
For now I suggest you do a couple of experiments and tell us the results. First, try the assignment with a short list of files (e.g. three) to verify that the assignment does what you intend. Second, in the directory with many files, try:
variable=$(shell ls -lart | grep name)
to see whether the problem is in grep or cut.
Rather than store the list of files in a variable you can easily use shell functionality to get the same result. It's a bit odd that you're flattening a recursive ls to only get the leaves, and then running mkdir -p which is really only useful if the parent directory doesn't exist, but if you know which depths you want to (for example the current directory and all subdirectories one level down) you can do something like this:
directories:
for path in ./*name* ./*/*name*; do \
mkdir "/some/path/$(basename "$path")" || exit 1; \
done
or even
find . -name '*name*' -exec mkdir "/some/path/$(basename {})" \;

typeset functions location

When I use the command typeset -f in ksh, a list of functions with their definition is displayed in stdout.
I tried to search where those functions are defined, but I couldn't find any hint about them. Can anyone help me finding them?
EDIT
I'm just learning the use of the typeset command, typing man typeset game me nothing (no manual entry for typeset).
In order to define functions that will be displayed using typeset -f, we need to define a function and export it using typeset -xf.
Functions can be declared in the .profile, or files called from .profile or put in a dir that is referenced by the FPATH variable (and proabably other places too). Read your man ksh carefully for the order of files that are processed on startup. Search for the 'Invocation', 'Files', and 'Functions' sections.
Also, there are a group of default functions that ksh sets up. So please edit your question to show the function names that your concerned with.
IHTH
Shells don't keep a record of where functions (or aliases, or variables, etc...) are defined. Conceptually, and notwithstanding interactive usage features like shell history, shells read commands from input one at a time, execute them, and then forget them. Sometimes those commands come from interactive input, sometimes they come from scripts. Sometimes they have side effects like defining a function in the shell's environment, but the shell still doesn't remember the command or its position in the shell's input stream after it's finished executing it.

get back to the previous location after 'cd' command?

I'm writing a shell script that needs to cd to some location. Is there any way to get back to the previous location, that is, the location before cd was executed?
You can simply do
cd -
that will take you back to your previous location.
Some shells let you use pushdir/popdir commands, check out this site. You may also find this SO question useful.
If you're running inside a script, you can also run part of the script inside a sub-process, which will have a private value of $PWD.
# do some work in the base directory, eg. echoing $PWD
echo $PWD
# Run some other command inside subshell
( cd ./new_directory; echo $PWD )
# You are back in the original directory here:
echo $PWD
This has its advantages and disadvantages... it does isolate the directory nicely, but spawning sub-processes may be expensive if you're doing it a lot. ( EDIT: as #Norman Gray points out below, the performance penalty of spawning the sub-process probably isn't very expensive relative to whatever else is happening in the rest of the script )
For the sake of maintainability, I typically use this approach unless I can prove that the script is running slowly because of it.
You could echo PWD into a variable and the cd back to that variable. It may be quieter.
Another alternative is a small set of functions that you can add to your .bashrc that allow you to go to named directories:
# cd /some/horribly/long/path
# save spud
# cd /some/other/horrible/path
# save green
...
# go spud
/some/horribly/long/path
This is documented at A directory navigation productivity tool, but basically involves saving the output of "pwd" into the named mnemonics ("spud" and "green") in the above case, and then cd'ing to the contents of the files.

How to make the glob() function also match hidden dot files in Vim?

In a Linux or Mac environment, Vim’s glob() function doesn’t match dot files such as .vimrc or .hiddenfile. Is there a way to get it to match all files including hidden ones?
The command I’m using:
let s:BackupFiles = glob("~/.vimbackup/*")
I’ve even tried setting the mysterious {flag} parameter to 1, and yet it still doesn’t return the hidden files.
Update: Thanks ib! Here’s the result of what I’ve been working on: delete-old-backups.vim.
That is due to how the glob() function works: A single-star pattern
does not match hidden files by design. In most shells, the default
globbing style can be changed to do so (e.g., via shopt -s dotglob
in Bash), but it is not possible in Vim, unfortunately.
However, one has several possibilities to solve the problem still.
First and most obvious is to glob hidden and not hidden files
separately and then concatenate the results:
:let backupfiles = glob(&backupdir..'/*').."\n"..glob(&backupdir..'/.[^.]*')
(Be careful not to fetch the . and .. entries along with hidden files.)
Another, perhaps more convenient but less portable way is to use
the backtick expansion within the glob() call:
:let backupfiles = glob('`find '..&backupdir..' -maxdepth 1 -type f`')
This forces Vim to execute the command inside backticks to obtain
the list of files. The find shell command lists all files (-type f)
including the hidden ones, in the specified directory (-maxdepth 1
forbids recursion).

Resources