issuing a bash command in multiple directories from a unix shell - unix

I need to execute a short script that just renames a few files (mv).
The script is in about 50 folders, each folder is named and currently I'm executing them from the shell and moving to the next folder using:
bash rename && cd ../folder01
Then pressing up and changing the last digit(s).
Is there a way to execute the script in all folders in one line?

Sure, use a for loop:
for f in folder*; do (cd "$f" && bash rename) ; done

Related

How can I save the path to a frequently used directory in UNIX?

Is there a way to save the path to a frequently used directory in UNIX, so instead of having to manually cd /path/to/directory I can just enter a shortcut cd myFavoritePath ??
Define your favorite directories in CDPATH environment variable. It's a colon-separated list of search paths available to the cd command. You should specify not a directory you want to switch but parent directory.
Here is brief info about it: http://docstore.mik.ua/orelly/unix/upt/ch14_05.htm
For example you have three directories you work with frequently:
/home/user/scripts/favorite/
/var/log/
/var/lib/
add to your ~/.bash_profile (or another shell profile file you use) the next line:
export CDPATH=.:/home/user/scripts:/var
In the example below I just redefine CDPATH in shell for the current session
[user#server lib]$ CDPATH=.:/var:/home/user/scripts
[user#server lib]$ cd log
/var/log
[user#server log]$ cd lib
/var/lib
[user#server lib]$ cd favorite
/home/user/scripts/favorite
If you want use tab while execute cd you can install bash-completion http://bash-completion.alioth.debian.org/ but it's optional
Also do not forget cd - command for quick switching to previous working dir
You can always add the directory path in ~/.bashrc
vi ~/.bashrc
export FAV_DIR1=''
The variables in .bashrc load into the environment on new session. So make sure to reboot.
Then you can visit the directory by something like:
cd $FAV_DIR1

How to diff all modifications of all checkout files under a directory recursively with Clearcase?

I'm using ClearCase. I checked out several files under a directory, some of files in its sub-directory, some in sub-sub-directory.
What I want is to list the diff of all my modifications on these checked out files under this certain directory recursively.
What I currently do is:
for file in $(cleartool lsco -recurse -me -cview -fmt "%n\n"); do
cleartool diff -serial_format -pred $file;
done
I use a bash for loop, but I perhaps it can be done with a simple ClearCase command.
The OP suggests using the list of checked out files, but there is no way to find the diff in one cleartool command.
An xargs (used here) might be easier
cleartool lsco -recurse -me -cview -fmt "%n\n" | xargs -n 1 cleartool diff -serial_format -pred

How do get my script file to console via Notepad++ external command?

I am using Notepad++ for creating scripts and opening my active files from menu "Run" -> "Open current dir cmd". This works fine and the result is:
c:\scripts>
What I would like to have is the filename that I am working on currently so that I could try testing it right away. In my scripts I use parameters to define input and output files. Therefore the script shouldn't be run while opening, rather to have the script typed into console:
c:\scripts>edit_text.pl
I would then add manually the needed input and output files
c:\scripts>edit_text.pl input.txt output.txt
How do I make this possible in Notepad++ "Run" -feature?
Currently it is defined in shortcuts.xml as
cmd /K cd $(CURRENT_DIRECTORY)
I suspect that it would be something like this:
cmd /K cd $(CURRENT_DIRECTORY) $(FILE_NAME)
The problem is that this will "execute" the filename as well. I would like to have it waiting on the console for my actions.
Thanks in advance!
The final code line would mean the CD and the script invocation being treated as one command. Separating then with && should help.
cmd /K cd $(CURRENT_DIRECTORY) && $(FILE_NAME)
However, that would do the CD then execute the command. I do not know of any way to enter a command but not execute it.
A poor solution would use the command below. You could copy and paste the echoed command then add in any parameters needed. Setting "Quick edit" mode on the window would make the copy and paste quicker.
cmd /K cd $(CURRENT_DIRECTORY) && ECHO $(FILE_NAME)
I have adopted a different approach for my own scripts although they do not have parameters that I need to enter. Edit the file (but not with Notepad++ as it overwrites the file just before it exits):
C:\Users\AdrianHHH\AppData\Roaming\Notepad++\shortcuts.xml
I have added some lines to the <UserDefinedCommands> section:
<NotepadPlus>
... unchanged
<UserDefinedCommands>
... unchanged
<Command name="Open containing folder" Ctrl="no" Alt="no" Shift="no" Key="0">explorer $(CURRENT_DIRECTORY)</Command>
<Command name="Open current dir cmd" Ctrl="no" Alt="no" Shift="no" Key="0">cmd /K cd /d $(CURRENT_DIRECTORY)</Command>
<Command name="Run as command" Ctrl="no" Alt="no" Shift="no" Key="0">cmd /C "cd /d $(CURRENT_DIRECTORY) && $(FULL_CURRENT_PATH)"</Command>
<Command name="Explorer with selection" Ctrl="no" Alt="no" Shift="no" Key="0">explorer $(CURRENT_WORD)</Command>
</UserDefinedCommands>
... unchanged
</NotepadPlus>

execute command in subdirectories

I want to run a program for a file that exists in different subdirectories and then redirect the output to an output file. I want the output to be saved to the directory that the program has run.
So I would like to do something like this:
for x in */*.txt; do command $x > output.fsa; done
My questions are:
Is it correct the above loop? should I change directory in order to save the output on the directory that the command was executed or linux takes care of it?
any ideas on how to give the name of the directory in the output file?
Is it correct the above loop?
Yes
should I change directory in order to save the output on the directory that the command was executed or linux takes care of it?
You do not need to change the directory it is enough to redirect the output to a file in the correct directory:
for x in */*.txt; do command $x > `dirname $x`/output.fsa; done
The loop is correct, you will iterate over all txt files in subdirs of the current pwd (where this script or command is being executed). You don't have to change directory to save the output in that subdir. Linux don't take care of it :)
You can delete everything after first / using variable expansion ${x%%/*}
Try
for x in */*.txt; do
command "$x" > "${x%%/*}"/output.fsa
done
Remember, if you have more txt files in that subdir, you will execute command "$x" more times and rewrite the output.fsa.
You can use append (>>) in that case
Try
for x in */*.txt; do
echo "Executing command \"$x\"" >> "${x%%/*}"/output.fsa
command "$x" >> "${x%%/*}"/output.fsa
done

Zip command without including the compressed dir itself

Suppose the structure:
/foo/bar/
--file1
--file2
--file3
--folder1
--file4
--folder2
--file5
I want to run the unix zip utility, compressing the bar folder and all of it's files and subfolders, from foo folder, but not have the bar folder inside the zip, using only command line.
If I try to use the -j argument, it doesn't create the bar folder inside the zip as I want, but doesn't create folder1 and folder2. Doing -rj doesn't work.
(I know I can enter inside bar and do zip -r bar.zip . I want to know if it's possible to accomplish what $/foo/bar/ zip -r bar.zip . but doing it from $/foo).
You have to do cd /foo/bar then zip -r bar.zip ., however, you can group them with parentheses to run in a subshell:
# instead of: cd /foo/bar; zip -r bar.zip; cd -
( cd /foo/bar; zip -r bar.zip . )
The enclosed (paren-grouped) commands are run in a subshell and cd within it won't affect the outer shell session.
See sh manual.
Compound Commands
A compound command is one of the following:
(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below).
Variable assignments and builtin commands that affect the shell's environment do not remain in effect after the command completes.
The return status is the exit status of list.
zip doesn't have a -C (change directory) command like tar does
you can do:
cd folder1 && zip -r ../bar.zip *
from within a command line shell
or you can use bsdtar which is a version of tar from libarchive that can create zips
bsdtar cf bar.zip --format zip -C folder1 .
(this creates a folder called ./ -- not sure a way around that)
I can't speak for the OP's reasoning. I was looking for this solution as well.
I am in the middle of coding a program that creates an .ods by building the internal xml files and zipping them together. They must be in the root dir of the archive, or you get an error when you try and run OOo.
I'm sure there is a dozen other ways to do this:
create a blank .ods file in OOo named blank.ods, extract to dir named blank, then try running:
cd blank && zip -r ../blank.ods *
The way I wrote mine, the shell closes after one command, so I don't need to navigate back to the original directory, if you do simply add && cd .. to the command line:
cd blank && zip -r ../blank.ods * && cd ..

Resources