Bash substring extraction purpose in "ls -lashtg ${1:-.}" [duplicate] - linux

This question already has answers here:
Usage of :- (colon dash) in bash
(2 answers)
Closed 1 year ago.
I ran across the following Bash function which was suggested as a useful alias to add to the .bashrc file. It lists the last 13 files in a directory that were modified.
I don't understand what is being done with the ${1:-.} argument, though. It looks like some kind of substring extraction, but I couldn't find the meaning of -. in the Advanced Bash Scripting Manual.
I tried the command in a few directories and didn't notice any difference between the output when I removed this argument. My guess is that it's there to prevent an error when encountering some specific type of file or file name. What is it doing? And what is the purpose of including it in the command?
function lst()
{
ls -lashtg ${1:-.} | head -13
}

$1 is the first command line argument. Im sure you know.
${1:-.} simply puts a . when no first line argument is given.
Thus
lst
Translates to
ls -lashtg . | head -13
It would workout without the substitution I guess. But I also guess that this is just there as a best practice

Related

Evaluating variable - output json file contents [duplicate]

This question already has answers here:
File content into unix variable with newlines
(6 answers)
Closed 4 years ago.
In the bash shell, I'm trying to read the json file and load to a variable
eri#xyz:~/Documents/inbound>e1=$(eval echo $(cat ./deploy/request.json))
Upon fetching the output of that variable, I'm seeing -bash - command not found along with the actual contents of the .json file
eri#xyz:~/Documents/inbound>"$e1"
-bash: { type:Pipeline, category:Software, risk:4, short_description:sample short description text, description:sample detailed description text, assignment_group: Services - Retail Services, cmdb_ci:Retail Service, u_version:1.0, start_date:2017-01-04 18:00:00, end_date:2017-01-04 19:00:00, backout_plan:see department for standard backout plan, implementation_plan:sample implementation plan, test_plan:sample text plan, production_system:false }: command not found
Is there a way to suppress the -bash - command not found in the output?.
No need for eval - just e1=$(< ./deploy/request.json) should do the trick. (Thanks to #shellter for the syntax — you don't even need to use cat!)
To show the variable, you want
echo "$e1"
instead of just "$e1". "$e1" by itself on the command line does not print out the value of $e1, unlike many programming-language REPLs. Instead, it tells bash to try to interpret the entire contents of $e1 as the name of a command. It isn't the name of a command, so bash tells you a command by that name cannot be found.

Extracting the file name from a full path string [duplicate]

This question already has answers here:
Get just the filename from a path in a Bash script [duplicate]
(6 answers)
Closed 4 years ago.
Let's say I have a string which represents the full path of a file:
full_path='./aa/bb/cc/tt.txt'.
How can I extract only the file name tt.txt?
Please don't tell me to use echo $full_path | cut -d'/' -f 5.
Because the file may be located in a deeper or shallower folder.
The number, 5, cannot be applied in all cases.
if you are comfortable with python then, you can use the following piece of code.
full_path = "path to your file name"
filename = full_path.split('/')[-1]
print(filename)
Use the parameter expansion functionality.
full_path='./aa/bb/cc/tt.txt'
echo ${full_path%/*}
That will give you the output
./aa/bb/cc
And will work any number of directory levels deep, as it will give you everything up to the final "/".
Edit: Parameter expansion is very useful, so here's a quick link for you that gives a good overview of what is possible: http://wiki.bash-hackers.org/syntax/pe
You can use this construct
echo "$full_path" | sed 's/\/.*\///'

Linux batch: create multi folder by combine name with serial number [duplicate]

This question already has answers here:
Command not found error in Bash variable assignment
(5 answers)
Closed 5 years ago.
I'm try to create multi folder by combine string and counter. I don't why what is the wrong with my code:
echo 'Start'
let count=0
for p in {1..10}
do
DirName= "dir"
NUM = "${DirName}${count}"
let count++
mkdir $NUM
mkdir "$NUM"/decoded
done
I got this kind of error
./test.sh: line 6: dir: command not found
./test.sh: line 7: NUM: command not found
thank in advance
No need to use a loop here. The shell will do all the necessary expansion for you. In fact, you're already relying on the shell to expand {1..10} for you as part of your for loop. So you can just use that expansion directly with mkdir. Also by using mkdir -p <path> (make parent directories as needed), you can avoid having to first do mkdir $NUM before doing mkdir $NUM/decoded.
Putting it all together, you can do what you need in a single line:
mkdir -p dir{1..10}/decoded
Edit: To answer your question more directly regarding the command not found errors, it looks like (as Bjorn A. mentioned) you just need to get rid of the spaces before and after the = in your variable assignments.
You cannot have spaces around the assignment operator in bash. Lines 6 and 7 must look like:
DirName="dir"
NUM="${DirName}${count}"

Read filename with * shell bash

I'am new in Linux and I want to write a bash script that can read in a file name of a directory that starts with LED + some numbers.(Ex.: LED5.5.002)
In that directory there is only one file that will starts with LED. The problem is that this file will every time be updated, so the next time it will be for example LED6.5.012 and counting.
I searched and tried a little bit and came to this solution:
export fspec=/home/led/LED*
LedV=`basename $fspec`
echo $LedV
If I give in those commands one by one in my terminal it works fine, LedV= LED5.5.002 but if i run it in a bash scripts it gives the result: LedV = LED*
I search after another solution:
a=/home/led/LED*
LedV=$(basename $a)
echo $LedV
but here again the same, if i give it in one by one it's ok but in a script: LedV = LED*.
It's probably something small but because of my lack of knowledge over Linux I cannot find it. So can someone tell what is wrong?
Thanks! Jan
Shell expansions don't happen on scalar assignments, so in
varname=foo*
the expansion of "$varname" will literally be "foo*". It's more confusing when you consider that echo $varname (or in your case basename $varname; either way without the double quotes) will cause the expansion itself to be treated as a glob, so you may well think the variable contains all those filenames.
Array expansions are another story. You might just want
fspec=( /path/LED* )
echo "${fspec[0]##*/}" # A parameter expansion to strip off the dirname
That will work fine for bash. Since POSIX sh doesn't have arrays like this, I like to give an alternative approach:
for fspec in /path/LED*; do
break
done
echo "${fspec##*/}"
pwd
/usr/local/src
ls -1 /usr/local/src/mysql*
/usr/local/src/mysql-cluster-gpl-7.3.4-linux-glibc2.5-x86_64.tar.gz
/usr/local/src/mysql-dump_test_all_dbs.sql
if you only have 1 file, you will only get 1 result
MyFile=`ls -1 /home/led/LED*`

recursively "normalize" filenames [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
recursively “normalize” filenames
Q on pastebin: http://pastebin.com/raw.php?i=19iYZpwY
i mean getting rid of special chars in filenames, etc.
i have made a script, that can recursively rename files [http://pastebin.com/raw.php?i=kXeHbDQw]:
e.g.: before:
THIS i.s my file (1).txt
after running the script:
This-i-s-my-file-1.txt
Ok. here it is:
But: when i wanted to test it "fully", with filenames like this [http://pastebin.com/raw.php?i=LQ07ntcS]:
¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÂÃÄÅÆÇÈÊËÌÎÏÐÑÒÔÕ×ØÙUÛUÝÞßàâãäåæçèêëìîïðñòôõ÷øùûýþÿ.txt
áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&'()+,:;<=>?#[]^_{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£.txt<br>
<br>
it fails [http://pastebin.com/raw.php?i=iu8Pwrnr]:<br>
$ sh renamer.sh directorythathasthefiles<br>
mv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()+,:;<=>?#[]^{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()*+,:;<=>?#[]^{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()+,:;<=>?#[]^_{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()+,:;<=>?#[]^{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()*+,:;<=>?#[]^{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()+,:;<=>?#[]^_{|}~€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ¡¢£': No such file or directorymv: cannot stat./áíüűúöőóéÁÍÜŰÚÖŐÓÉ!"#$%&\'()+,:;<=>?#[]^_`{|}~€‚ƒ„…†....and so on
$
so "mv" can't handle special chars.. :\
i worked on it for many hours..
does anyone has a working one? [that can handle chars [filenames] in that 2 lines too?]
Reading that script was almost painful...
For one, you should read this.
Then you should read about bash functions. After that you should read about sed and tr
Then you should consider this: do you really want to move the file each time that you perform a transformation on its name?
Then after all this thinking, you should come up with something a bit saner.
Wtf is going on your system? You should consider re setting up and pay attention on sane applicaitons and security.
However its very likely that you are just running into the max length of command arguments if i am looking at that.
If not, well install UTF8 locales and install them as system default.
On debian based systems this is usually just a matter of dpkg-reconfigure locales
also work on your accept rate.

Resources