how to use a string as an argument in an for ... in ... statement in linux shell - linux

I'm familiar with the structure of
for file in foo/folder\ with\ spaces/foo2/*.txt
do
#do some stuff...
done
However, I want to put foo/folder with spaces/foo2/*.txt into a variable and then use it. Something like this:
myDirectory="foo/folder with spaces/foo2/*.txt"
for file in $myDirectory
do
# do some stuff
done
But what I've written here doesn't work, and it won't work even if I do
myDirectory="food/folder\ with\ spaces/foo2/*.txt"
or
for file in "$myDirectory" ...
Any help? is this even possible?

don't parse ls
# your files are expanded here
# note lack of backslashes and location of quotes
myfiles=("food/folder with spaces/foo2/"*.txt)
# iterate over the array with this
for file in "${myfiles[#]}"; do ...

Parsing ls is a bad idea, instead just do the shell globbing outside of the quotes.
You could also do:
$mydir="folder/with spaces"
for file in "$mydir"/*; do
...
done
Also look into how find and xargs works. Many of these sort of problems can be solved using those. Look at the -print0 and -0 options in particular if you want to be safe.

Try using the ls command in the for loop. This works for me:
for file in `ls "$myDirectory"`

Related

how to specify path with space inside file in linux

cat ~/.last_dir
/mnt/c/Users/Administrator/OneDrive/Desktop/main project/backup/main project 2
cd cat ~/.last_dir
-bash: cd: too many arguments
I tried using backslash inside the file
/mnt/c/Users/Administrator/OneDrive/Desktop/main\ project/backup/main\ project\ 2
Still same error
You need to quote the results of expanding cat ...:
cd "$(cat ~/.last_dir)"
cd "$(<~/.last_dir)"
First, put quotes around the $(...) to make the space part of the filename.
Second, $(<...) is a bash construct that reads the file directly without executing cat, but is not entirely portable.
For a more generic, less bash-specific version, use Maxim's solution.
just put quotation marks around your path:
"/mnt/c/Users/Administrator/OneDrive/Desktop/main project/backup/main project 2"
this should work for most cases

Using for in a Script, Ubuntu command line

How can I pass each one of my repository files and to do something with them?
For instance, I want to make a script:
#!/bin/bash
cd /myself
#for-loop that will select one by one all the files in /myself
#for each X file I will do this:
tar -cvfz X.tar.gz /myself2
So a for loop in bash is similar to python's model (or maybe the other way around?).
The model goes "for instance in list":
for some_instance in "${MY_ARRAY[#]}"; do
echo "doing something with $some_instance"
done
To get a list of files in a directory, the quick and dirty way is to parse the output of ls and slurp it into an array, a-la array=($(ls))
To quick explain what's going on here to the best of my knowledge, assigning a variable to a space-delimited string surrounded with parens splits the string and turns it into a list.
Downside of parsing ls is that it doesn't take into account files with spaces in their names. For that, I'll leave you with a link to turning a directory's contents into an array, the same place I lovingly :) ripped off the original array=($(ls -d */)) command.
you can use while loop, as it will take care of whole lines that include spaces as well:
#!/bin/bash
cd /myself
ls|while read f
do
tar -cvfz "$f.tar.gz" "$f"
done
you can try this way also.
for i in $(ls /myself/*)
do
tar -cvfz $f.tar.gz /myfile2
done

Add extra file extension to all filenames in a directory via Linux command line

I want to add the ".sbd" after all files ending on ".utf8" in a directory
I do not want to replace the extensions, but really want to add them so the filenames will look like "filename.utf8.sbd"
I think I should adapt the following code, but don't manage to find out exactly how
for f in *.utf8 ; do mv "$f" "$f.sbd" ; done
Can anyone help me? I am very new to the command line
Thanks a bunch!
Your code should work if no file has spaces (or other "special" character) in the name and if the directory is not pathologically big.
In those cases, you can use something like this:
ls|grep '*.utf8$'|while read i; do mv "$i" "$i.sbd"; done

Like a vlookup but in bash to match filenames in a directory against a ref file and return full description

I am aware there isn't a special bash function to do this and we will have to build this with available tools -- e.g. sed, awk, grep, etc.
We dump files into a directory and while their filename looks random, they can be mapped to their full description. For example:
/tmp/abcxyz.csv
/tmp/efgwaz.csv
/tmp/mnostu.csv
In filemapping.dat, we have:
abcxyz, customer_records_abcxyz
efgwaz, routernodes_logs_efgwaz
mnostu, products_campaign
We need to go through each of them in the directory recursively and rename the file with its full description. Final outcome:
/tmp/customer_records_abcxyz.csv
/tmp/routernodes_logs_efgwaz.csv
/tmp/products_campaign_mnostu.csv
I found something similar here but not sure how to work it out at directory level dealing with only one file as the lookup/referece file. Please help. Thanks!
I would try something like this:
sed 's/,/.csv/;s/$/.csv/' filemapping.dat | xargs -n2 mv
Either cd to tmp beforehand, or modify the sed command to include the path name.
The sed commands simply replace the comma and the line end with the string ".csv".

linux batch rename directories and strip # character from name

i have a directory with a lot of subdirectories with a # infront of them:
#adhasdk
#ad18237
I want to rename them all and remove the # caracter
I tried to do:
rename -n `s/#//g` *
but didn't seem to work.
-bash: s/#//g: No such file or directory
Any ideas on this.
Thanks
Just use
$ rename 's/^#//' *
use -n just to check that what you think it would happen really happens.
In you example you have the clue about the wrong quotes used (backticks) in the error message
-bash: s/#//g: No such file or directory
bash is trying to execute a command named s/#//g.
No that using g (global) and not anchoring the regular expression you will replace any #, not just the one in the first position.
I don't know whether it's just a typo when you typed it here, but that "rename" command should work if:
you leave off the "-n" and
you quote the substitution with regular single-quotes and not back-quotes
The "-n" tells it to not really do anything. The back-quotes are just wrong (they mean something but not what you want here).
The problem is that you use backticks (`). You should use normal quotes:
rename -n 's/#//g' *
for DIR in \#*/
do
echo mv "$DIR" "${DIR/#\#/}"
done
I had to rename all folders inside a given folder. Each folder name had some text inside round braces. The following command removed the round braces from all folder names:
rename 's/(.+)//' *
Some distros doesn't support regexp in rename. You have to install prename. Even more, sometimes you can't install prename and you have to install gprename to have binary prename.
If you have 'prename' then just change backtick character " ` " to single quote and everything should work.
So the solution should be:
prename -n 's/#//g' *
or
prename -n 'y/#//' *

Resources