I need to make an array containing over 100 different image names and I wonder if there is any way to "convert" the image names from a folder into a .txt file using terminal to then paste them into xcode instead of manually write all of them. Any advice?
You can go to terminal and type
ls # list files
ls -lt # list files with details
ls *.jpg # list only jpg files
ls > files.txt # list files and write them to files.txt
The # by the way, is just a comment. You can combine the above commands.
Although I need to say, that the PROPER way of doing this, is letting you code find those files in the desired directory, unless there's a good reason for not doing so.
Related
I like to create tar-files to distribute some scripts using bash.
For every script certain configuration-files and libraries (or toolboxes) are needed,
e.g. a script called CheckTool.py needs Checks.ini, CheckToolbox.py and CommontToolbox.py to run, which are stored in specific folders on my harddisk and need to be copied in the same manner on the users harddisk.
I can create a tarfile manually for each script, but i like to have it more simple.
For this i have the idea to define a list of all needed files and their pathes for a specific script and read this in a bashscript, which creates the tar file.
I started with:
#!/bin/bash
while read line
do
echo "$line"
done < $1
Which is reading the files and pathes. In my example the lines are:
./CheckTools/CheckMesh.bs
./Configs/CheckMesh.ini
./Toolboxes/CommonToolbox.bs
./Toolboxes/CheckToolbox.bs
My question is how do I have to organize the data to make a tar file with the specified files using bash?
Or is there someone having a better idea?
No need for a complicated script, use option -T of tar. Every file listed in there will be added to the tar file:
-T, --files-from FILE
get names to extract or create from FILE
So your script becomes:
#!/bin/bash
tar -cvpf something.tar -T listoffiles.txt
listoffiles.txt format is super easy, one file per line. You might want to put full path to ensure you get the right files:
./CheckTools/CheckMesh.bs
./Configs/CheckMesh.ini
./Toolboxes/CommonToolbox.bs
./Toolboxes/CheckToolbox.bs
You can add tar commands to the script as needed, or you could loop on the list files, from that point on, your imagination is the limit!
Basically I have .bz2.gz.bz2 file which on extraction gives a .bz2.gz file and on again extraction gives .bz2 file. In this .bz2 file, is my txt file which I want to search on using grep command. I have searched for this but I got bzgrep command which will only search in bz2 file and not the corresponding .gz.bz2 file and give me no results.
Is there a command in unix system which will recursively search in a zipped archive for zipped archive and return results only when it finds the txt file inside it?
P.S: the txt file may be deep in the archive to level 10 max. I want the command to recursively find the txt file and search for the required string. And there will be no other than an archive inside the archive until the txt file level.
I'm not sure I fully understand but maybe this will help:
for i in /path/to/each/*.tar.bz2; do
tar -xvjf "$i" -C /path/to/save/in
rm $i
done
extract all `tar.bz2` and save them in directory then remove the `.bz2`
Thnx for sharing your question.
There are a couple of strange things with it though:
It makes no sense to have a .bz2.gz.bz2 file, so have you created this file yourself? If so, I'd advise you to reconsider doing so in that manner.
Also, you mention there is a .bz2 that would apparently contain different archives, but a .bz2 can only contain one single file by design. So if it contains archives it is probably a .tar.bz2 file in which the tar-file holds the actual archives.
In answer to your question, why can't you write a simple shell script that will unpack your .bz2.gz.bz2 into a .bz2.gz and then into a .bz2 file and then execute your bzgrep command on that file?
I do not understand where it is exactly that you seem to get stuck..
I have to do some things in some files from a directory in solaris. In that directory, I have thousands of files. Some of them, begin with FAC_. I need to make an array variable with those names of files (which four first letters name are FAC_), and then go over the array to do some task to each file.
How can I accomplish that?
Thanks
I think the simplest approach would be something like this:
files="FAC_*"
for file in $files; do
echo "$file"
done
If the files aren't in the same directory as the script you can use the following line to retrieve them.
files="$path/FAC_*"
I have a lot of files named the same, with a directory structure (simplified) like this:
../foo1/bar1/dir/file_1.ps
../foo1/bar2/dir/file_1.ps
../foo2/bar1/dir/file_1.ps
.... and many more
As it is extremely inefficient to view all of those ps files by going to the
respective directory, I'd like to copy all of them into another directory, but include
the name of the first two directories (which are those relevant to my purpose) in the
file name.
I have previously tried like this, but I cannot get which file is from where, as they
are all named consecutively:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Where ../plots is the folder where I copy them. However, they are now of the form file.ps.~x~ (x is a number) so I get rid of the ".ps.~*~" and leave only the ps extension with:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Then, as the ps files have hundreds of points sometimes and take a long time to open, I just transform them into jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
This is not really a working bash script as I have to change the directory manually.
I guess the best way to do it is to copy the files form the beginning with the names
of the first two directories incorporated in the copied filename.
How can I do this last thing?
If you just have two levels of directories, you can use
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
This goes over each ps file, and hard links them to the current directory with the /s replaced by _. Use cp instead of ln if you intend to edit the files but don't want to update the originals.
For arbitrary directory levels, you can use the bash specific
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
But are you sure you need to copy them all to one directory? You might be able to open them all with yourreader */*/*.ps, which depending on your reader may let browse through them one by one while still seeing the full path.
You should run a find command and print the names first like
find . -name "file_1.ps" -print
Then iterate over each of them and do a string replacement of / to '-' or any other character like
${filename/\//-}
The general syntax is ${string/substring/replacement}. Then you can copy it to the required directory. The complete script can be written as follows. Haven't tested it (not on linux at the moment), so you might need to tweak the code if you get any syntax error ;)
for filename in `find . -name "file_1.ps" -print`
do
newFileName=${filename/\//-}
cp $filename YourNewDirectory/$newFileName
done
You will need to place the script in the same root directory or change the find command to look for the particular directory if you are placing the above script in some other directory.
References
string manipulation in bash
find man page
To create a playlist for all of the music in a folder, I am using the following command in bash:
ls > list.txt
I would like to use the result of the pwd command for the name of the playlist.
Something like:
ls > ${pwd}.txt
That doesn't work though - can anyone tell me what syntax I need to use to do something like this?
Edit: As mentioned in the comments pwd will end up giving an absolute path, so my playlist will end up being named .txt in some directory - d'oh! So I'll have to trim the path. Thanks for spotting that - I would probably have spent ages wondering where my files went!
The best way to do this is with "$(command substitution)" (thanks, Landon):
ls > "$(pwd).txt"
You will sometimes also see people use the older backtick notation, but this has several drawbacks in terms of nesting and escaping:
ls > "`pwd`.txt"
Note that the unprocessed substitution of pwd is an absolute path, so the above command creates a file with the same name in the same directory as the working directory, but with a .txt extension. Thomas Kammeyer pointed out that the basename command strips the leading directory, so this would create a text file in the current directory with the name of that directory:
ls > "$(basename "$(pwd)").txt"
Also thanks to erichui for bringing up the problem of spaces in the path.
This is equivalent to the backtick solution:
ls > $(pwd).txt
To do literally what you said, you could try:
ls > `pwd`.txt
which will use the full pathname, which should be fine.
Note that if you do this in your home directory, which might
be in /home/hoboben, you will be trying the create /home/hoboben.txt,
a text file in the directory above.
Is this what you wanted?
If you wanted the directory to contain a file named after it, you would get
the basename of the current directory and append that with .txt to the pwd.
Now, rather than use the pwd command... why not use the PWD environment variable?
For example:
ls > $PWD.txt
or
ls > ${PWD}.txt
is probably what you were trying to remember with your second example.
If you're in /home/hoboben and you want to create /home/hoboben/hoboben.txt, try:
ls > ${PWD}/${PWD##*/}.txt
If you do this, the file will contain its own name, so most often, you would remedy this in one of a few ways. You could redirect to somewhere else and move the file or name the file beginning with a dot to hide it from the ls command as long as you don't use the -a flag (and then optionally rename the resulting file).
I write my own scripts to manage a directory hierarchy of music files and I use subdirectories named ".info", for example, to contain track data in some spare files (basically, I "hide" metadata this way). It works out okay because my needs are simple and my collection small.
I suspect the problem may be that there are spaces in one of the directory names. For example, if your working directory is "/home/user/music/artist name". Bash will be confused thinking that you are trying to redirect to /home/user/music/artist and name.txt. You can fix this with double quotes
ls > "$(pwd).txt"
Also, you may not want to redirect to $(pwd).txt. In the example above, you would be redirecting the output to the file "/home/user/music/artist name.txt"
The syntax is:
ls > `pwd`.txt
That is the '`' character up underneath the '~', not the regular single quote.
Using the above method will create the files one level above your current directory. If you want the play lists to all go to one directory you'd need to do something like:
#!/bin/sh
MYVAR=`pwd | sed "s|/|_|g"`
ls > /playlistdir/$MYVAR-list.txt
to strip all but the directory name
ls >/playlistdir/${PWD##/*}.txt
this is probably not what you want because then you don't know where the files are (unless you change the ls command)
to replace "/" with "_"
ls >/playlistdir/${PWD//\//_}.txt
but then the playlist would look ugly and maybe not even fit in the selection window
So this will give you both a short readable name and usable paths inside the file
ext=.mp3 #leave blank for all files
for FILE in "$PWD/*$ext"; do echo "$FILE";done >/playlistdir/${PWD##/*}.txt