What does "?" mean in Unix/Linux? [duplicate] - linux

This question already has an answer here:
Bash - meaning of a simple question mark (?)
(1 answer)
Closed 23 days ago.
I'm currently learning Bash and trying to understand some lines of code which I've found.
So from my understanding,
* refers to everything within the specified file/directory
? refers to one single character
and based off this understanding, I found the code down below and I'm trying to understand it but to no avail.
Can someone please explain what is happening in this line of code?
mv public_html/*.??g public_html/images/

mv public_html/*.??g public_html/images
Move all files in the directory public_html that have a 3 character extension ending in g to its subfolder images.

* is not everything in the directory unless it is all by itself.
public_html/*.??g --> public_html/ anything . single character single character g
Technically, * isn't anything either, it's anything that isn't a /
This may match multiple files, which is ok, because the last pathname on the line appears to be a directory.
To describe this in words, move anything in the public_html directory that ends in a three letter file extension ending in g into the images subdirectory.

Related

Bash shell script postprocessing results of ls [duplicate]

This question already has answers here:
What is the meaning of the ${0##...} syntax with variable, braces and hash character in bash?
(4 answers)
What does "##" in a shell script mean? [duplicate]
(1 answer)
Closed 7 months ago.
I came across a shell script like the following:
for FILE_PATH in `ls some/directory`
do
export FILE=${FILE_PATH##*/}
done
What exactly is the "##*/" doing? When I echo ${FILE} and ${FILE_PATH}, I don't see any difference. Is this to handle unusually named files?
More generally, how would I go about figuring out this type of question for myself in the future? Google was completely useless.
It's removing everything up to the last / in the value of $FILE. From the Bash Manual:
${parameter#word}
${parameter##word}
The word is expanded to produce a pattern and matched according to the rules described below (see Pattern Matching). If the pattern matches the beginning of the expanded value of parameter, then the result of the expansion is the value of parameter with the shortest matching pattern (the ‘#’ case) or the longest matching pattern (the ‘##’ case) deleted.
You're not seeing any difference in this case because when you list a directory it just outputs the filenames, it doesn't include the directory portion, so there's nothing to remove. You would see the difference if you did:
for FILE in some/directory/*

How to rename multiple files in a directory leaving the extension in Linux [duplicate]

This question already has answers here:
How to rename files without changing extension in Linux 102221.pdf to 102221_name.pdf
(3 answers)
Rename multiple files based on pattern in Unix
(24 answers)
Closed 4 years ago.
I need to rename files in a directory taking out a string of characters that is different with each file but starts the same way. I know how to strip characters from the filename, but how do I preserve the extension? I know it's a variation of a common question but I can't find a answer that fits my exact need.
Redshirts_ep6_dSBHpCsvQ3BfQ7-NNIjXYO4pnHpNMvu7bfvURLF3BSzB_3YOOrBBoNnICTR-hg.mp3
-> Redshirts.mp3
PathsNotTaken_ep6_XWixFER4PJyeozVfcxT96UajpnVI7cRMRhAU4Aj9-rpeacnBleuGY9zCPDe0aQ.mp3
-> PathsNotTaken.mp3
The linux command rename is super helpful here. It can use regex to perform the renaming.
This can probably rewritten a bit, but it appears do to the job here:
rename -n 's/(^[^_]*)_.*/$1.mp3/' *.mp3
Just remove that -n flag to run for for real. Leaving it on is just a test.
This regex says:
Characters at the start of the line ^ that don't contain an underscore [^_] repeated any number of times * are captured into a capture group (^[^_]*) if they are followed by an underscore and any number of any other characters _.*. These are then rewritten by using that first capture group $1 followed by .mp3

Linux script change file name,folder name and ingridents

I have a long folder/file structure with bunch of code files in it. some of my files has "x5g6" pattern on their name, on the folder name and also the text inside the files.
e.g
/Mycodes
/pp_x5g6
- vbg_x5g6.cmd
- x5g6_pp
- x5g6_pp.ml
so on so forth
also if you open vbg_x5g6.cmd file you can see there is a code in it and it also has this pattern (e.g function bb_x5g6 = x+ y);
My question is which commands I can use to recursively change x5g6 into x5g7
on folder, file names and also inside the files?
So far I could only found;
find . -type f -exec sed -i 's/x5g6/x5g7/g' {} +
but this only changes whatever inside the files not the folder and file names.
It looks like you have a solution already for editing the file contents.
For the file/directory names, I believe the generally accepted answers are to use either a program called mmv, (which I, myself, prefer), or one called rename
For the record, this question is a duplicate of https://unix.stackexchange.com/questions/98070/rename-files-in-directory.
The original there contains an answer also recommending zmv (if you're using zsh instead of bash).
edit: grammar

How to remove comments of ASM code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I have an directory with about 300 source code in ASM.
So, I need to remove the comments (";") of this codes.
Until now, I removed the comments of 3 files, where each file has 100 lines of code.
Somebody know a script that can help me?
Sed is your friend:
find <asm_dir> -type f | xargs sed -i -e '/^;/d' -e 's/^\([^;]*\);.*$/\1/'
The first expression deletes lines that begin with the comment character ;. The second expression strips inline comments (from ; to the end of the line).
You can simply accomplish this in e.g. Vim or Emacs. I'm going to discuss Vim here.
Assuming you have all your .asm files in one directory go to your shell and do something like
cd /path/to/my/files
gvim *.asm
This will open all your .asm files for editing in gvim (graphical vim). If you are not familiar with Vim it's a great text editor and we are going to record a macro to do our job. Only do what I say or you will mess things up :) To be on the safe side you should backup your files in case you mistype something and delete more than you wish to.
Type these characters (or press the appropriate thing on your keyboard as specified in <>'s):
qa:g/^\s*;/d<Enter>:n<Enter>q
This will start recording a macro [q], store it in [a], execute a global deletion of every line in the first file that starts with optional whitespace followed by a semicolon [:g/^\s*;/d<Enter>], move to the next file [:n<Enter>] and save the macro [q]. All you have to do now is run this macro as many times as you have files left. You can either get this by running ls *.asm | wc -l in your directory with the saved files or you can simply overshoot it and input a larger number, Vim will stop on the last file and notify you there's no more files to edit. So with the overshooting example you could type
1000#a
and the macro will start running through all the files. This may take some time so be patient. Once it's done we still haven't saved our files so we could check the results before commiting to them. You can check a couple of files if they look OK and if yes type
:wa<Enter>
All your files are saved now and you can exit Vim with ZQ or :q<Enter>.

Search files with multiple "dot" characters

In Linux how do I use find and regular expressions or a similar way without writing a script to search for files with multiple "dots" but IGNORE extension.
For e.g search through the following files will only return the second file. In this example ".ext" is the extension.
testing1234hellothisisafile.ext
testing.1234.hello.this.is.a.file.ext
The solution should work with one or more dots in the file name (ignoring the extension dot). This should also work for any files i.e. with any file extension
Thanks in advance
So if I understand correctly, you want to get the filenames with at least two additional dots in the name. This would do:
$ find -regex ".*\.+[^.]*\.+[^.]*\.+.*"
./testing.1234.hello.this.is.a.file.ext
./testing1234.hellothisisafile.ext
$ find -regex ".*\.+[^.]*\.+[^.]*\.+[^.]*\.+.*"
./testing.1234.hello.this.is.a.file.ext
The key dot detecting part is \.+ (at least one dot), coupled with the separating anything (but a dot, but the previous part covers it already; a safety measure against greedy matching) [^.]*. Together they make the core part of the regex - we don't care what is before or after, just that somewhere there are three dots. Three since also the one from the current dir matters — if you'll be searching from elsewhere, remove one \.+[^.]* group:
$ find delme/ -regex ".*\.+[^.]*\.+[^.]*\.+[^.]*\.+.*"
delme/testing.1234.hello.this.is.a.file.ext
$ find delme/ -regex ".*\.+[^.]*\.+[^.]*\.+.*"
delme/testing.1234.hello.this.is.a.file.ext
In this case the result is the same, since the name contains a lot of dots, but the second regex is the correct one.

Resources