for example
echo "filename.pdf" | cut -d'.' -f 1
This way I get the "filename" string.
I'd like to store it in a variable called FILE and then use it like this:
DIR=$PATH/$FILE.txt
So, my script wants to create a file.txt with the same name of the pdf (not a copy of the file, just the name)
This way I tried to assign the result of echo | cut
FILE=
but I get only "path/.txt" so the filename is missing.
FILE=$(echo "filename.pdf" | cut -d'.' -f 1)
So, my script wants to create a file.txt with the same name of the pdf
You can use BASH string manipulation:
s="filename.pdf"
p="${s/%.pdf/.txt}"
echo "$p"
filename.txt
POSIX parameter expansion would read
file=filename.pdf
filename="${file%%.*}" # Two % will remove multiple extensions, if applicable
dir=$path/$filename.txt
Related
I'm studying about how to use 'cut'.
#!/bin/bash
for file in *.c; do
name = `$file | cut -d'.' -f1`
gcc $file -o $name
done
What's wrong with the following code?
There are a number of problems on this line:
name = `$file | cut -d'.' -f1`
First, to assign a shell variable, there should be no whitespace around the assignment operator:
name=`$file | cut -d'.' -f1`
Secondly, you want to pass $file to cut as a string, but what you're actually doing is trying to run $file as if it were an executable program (which it may very well be, but that's beside the point). Instead, use echo or shell redirection to pass it:
name=`echo $file | cut -d. -f1`
Or:
name=`cut -d. -f1 <<< $file`
I would actually recommend that you approach it slightly differently. Your solution will break if you get a file like foo.bar.c. Instead, you can use shell expansion to strip off the trailing extension:
name=${file%.c}
Or you can use the basename utility:
name=`basename $file .c`
You should use the command substitution (https://www.gnu.org/software/bash/manual/bashref.html#Command-Substitution) to execute a command in a script.
With this the code will look like this
#!/bin/bash
for file in *.c; do
name=$(echo "$file" | cut -f 1 -d '.')
gcc $file -o $name
done
With the echo will send the $file to the standard output.
Then the pipe will trigger after the command.
The cut command with the . delimiter will split the file name and will keep the first part.
This is assigned to the name variable.
Hope this answer helps
Hello guys I wrote code in linux shell script but the code only read from keyboard i want to change it to read from file for example if i write ./car.sh lamborghini.txt it should give me most expensive model of it.
code is like this:
#!/bin/sh
echo "Choose one of them"
read manu
sort -t';' -nrk3 auto.dat > auto1.dat
grep $manu auto1.dat | head -n1 | cut -d';' -f2
and auto.dat file contains these:
Lamborghini;Aventador;700000
Lamborghini;Urus;200000
Tesla;ModelS;180000
Tesla;ModelX;140000
Ford;Mustang;300000
Ford;Focus;20000
The read command always reads from stdin. You can use redirection < to read the content of a file.
Reading $manu from a file's content
#!/bin/sh
read manu < "$1"
sort -t';' -nrk3 auto.dat | grep "$manu" | head -n1 | cut -d';' -f2
This version of your script expects a file name as a command line parameter. The first line of said file will be stored in $manu. Example:
./car.sh fileWithSelection.txt
The file should contain the text you would have entered in your old script.
Reading $manu from a command line parameter
In my opinion, it would make more sense to interpret the command line parameters directly, instead of using files and passing them to the script.
#!/bin/sh
manu="$1"
sort -t';' -nrk3 auto.dat | grep "$manu" | head -n1 | cut -d';' -f2
Example:
./car.sh "text you would have entered in your old script."
You can try this way but the file Tesla.txt must contain Tesla
#!/bin/sh
read manu < "$1"
awk -F\; -vmod="$manu" '
$1==mod{if($3>a){a=$3;b=$2}}
END{if(b){print "The more expensive "mod" is "b" at "a}}' auto.dat
Every line printed with the echo includes the forward slashes for the directories that the given files are in. I am trying to cut the forward slashes using the cut command but it is not working. The files are gzipped so they have the .gz extension.
#!/bin/bash
for filename in /data/logs/2017/month_01/201701*
do
echo $filename
cut $filename -d '/' -f1
done
Thanks in advance.
The order of commands is wrong. You need to stream the string input to the cut command via pipe(|) or here-strings(<<<).
echo "$filename" | cut -d '/' -f1
(or)
cut -d '/' -f1 <<<"$filename"
(or) using here-docs
cut -d '/' -f1 <<EOF
$filename
EOF
data
And don't forget to double-quote variables to avoid Word-Splitting done by the shell.
Assuming filename is /a/b/c.gz you just want c.gz ?
Well there's two very easy answers:
basename $filename
The other is:
echo ${filename##*/}
The latter make use bash's built-in string delete parameter expansion.
Another way of solving your problem, is you could change directory first, i.e.
#!/bin/bash
pushd /data/logs/2017/month_01
for filename in 201701*
do
echo $filename
done
popd
Reference:
http://wiki.bash-hackers.org/syntax/pe
(EDIT: Fixed typo identified by #123)
As suggested b #lnian cut command used with echo command via pipe sign
For getting only file name with your script you need to use.
cut with -f1 option will get first value before / which would give blank so you need to get last value from the filename.
#!/bin/bash
for filename in /data/logs/2017/month_01/201701*
do
echo "$filename" | rev| cut -d '/' -f1
done
rev command reverse the filename so you will get last value which is your filename
I have a file named "01 - Welcome To The Jungle.mp3", and I want to do eyeD3 -t "Welcome To the Jungle" 01 - Welcome To The Jungle.mp3 to modify the tag of the all the files in the folder. I've extracted from the file with awk: "Welcome To The Jungle" doing:
#!/bin/bash
for i in *.mp3
do
eyeD3 -t $(echo ${i} | awk -F' - ' '{print $2}' | awk -F'.' '{print $1}') ${i}
done
It doesn't work. Neither the whole "$(echo S{i}....)" nor the "${i}" seem to work for replacing the names of the respective files.
You need to prevent word splitting on IFS (default: space, tab, newline) by shell, as your input filename contains space(s). The typical workaround is to use double quotes around the variable expansion.
Do:
for i in *.mp3; do eyeD3 -t "$(echo "$i")" | ...; done
You can leverage here string, <<<, to avoid the echo-ing:
for i in *.mp3; do eyeD3 -t <<<"$i" | ...; done
You need to double-quote variables that may contain spaces, as #heemayl already pointed out.
Also, in this example, instead of using awk,
it would be better to use native Bash pattern substitution to extract the title, for example:
for file in *.mp3; do
title=${file%.mp3}
title=${title#?????}
eyeD3 -t "$title" "$file"
done
That is:
Remove .mp3 at the end
Remove the first 5 characters (the count prefix NN -)
There is a parameter that I need to grep from a file and then I need to get that parameter into another file. I need to read the variable at boot time and have it inserted in
$grep "id" /file/one | cut -d " " -f2
$12345
So now I have the ID_VAR of 12345. Now what I would like to do is use this in /file/two
In file/two:
...
#program ID_VAR
...
Is there a way to run the grep function inside file two? Is there a way to share a variable between files? I am using Debian.
grep an id from one file and append to another file prepended with the string #program:
echo '#program' $(grep "id" file/one | cut -d " " -f2) >> file/two
There are some ambiguities in your question, but I think this snippet of script is what you are looking for:
Assuming #program is already in your file 2: (otherwise, see sudo_o's solution)
ID_VAR=$(grep "id" /file/one | cut -d " " -f2)
sed -i "s/#program/#program ${ID_VAR}/" /file/two
Explanation:
ID_VAR=$(...): save of the result of your grep and cut into ID_VAR
sed: invoke sed and use the -i option to edit the input file in place
"s/#program/#program ${ID_VAR}/": replace #program with #program (value of ID_VAR) in the input file
/file/two: what your input file is