Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Please excuse me for my amateur language.
I have written a simple one line code to cat out content I want from a huge text file:
cat file | grep "value" | cut -f1 -d":"
It out put lines of paths of file from there on.
I want it to go on doing this:
cd into the paths one line at a time.
each time after cd run this command:
ls | grep .fileformat
Then let me run 3 commands I choose to, if I press [return] with no value it will ignore and listen for the next command. After three is done it will go on.
cd into the directory of the next line and repeating until the last line.
Sorry I couldn't figure this later part out as I didn't know where to start googling even.
Thank you for looking!
Edit 1: output of my initial command gives paths like this:
/home/user/path/to/file
So there is no ~, it should be able to cd into them no problem?
A slightly modified version of Allan Wind's answer that does what I THINK the OP wants (tried to reply as a comment to Allan but couldn't figure out code formatting properly):
sed -n '/value/s/\([^:]*\):.*/\1/p' file | while read d
do
echo -e "Entering $d"
cd $d
ls | grep .fileformat
for i in {1..3}; do
echo -e "Type your command #${i}:\n"
read -p '>' input < /dev/tty
[ -z "$input" ] && echo -e "\nDoing nothing this time...\n" && continue
eval "$input"
done
done
(Usual caveats of reading interactively + using eval being dangerous)
Here is the skeleton of an answer to help you ask a better question:
sed -n '/value/s/\([^:]*\):.*/\1/p' file | while read d
do
(
cd d
ls | grep .fileformat
read -p "3 commands? " c
[ -z "$c" ] && continue
cd d
eval "$c"
)
done
(Usual caveats of reading interactively + using eval being dangerous)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
When I run this code, the variable "thing" doesn't change its value to the command. I've tried everything and I just can't get it to work. I want thing to equal something like "1 history cd /bin
history cd /home/user/"
#!/bin/bash
val="thing"
function send () {
thing
thing=$(history | tail -n 2)
echo $thing
echo $val
# echo $last
if [ "$val" == *"this"* ]; then
echo "yes"
fi
exit 1
}
send
If you wonder why $(history | tail -n 2) returns nothing, it is because history lists commands previously ran in the current shell.
But your script is a new shell instance, so it does not carry the history of commands you ran before you execute your script.
If you want that, you have to source the script, not execute it. To source, do:
$ . thescript.bash
instead of
$ ./thescripts.bash
instead of this also
$ bash thescript.bash
Note: put your code in https://www.shellcheck.net/ to see syntax issues.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am completely new to bash and am trying to practice with various simple tasks. If given a text file, how can I output the words in the file with their frequencies? For example if the text file contained "I really really love burgers" the output should look like:
Burgers 1
I 1
Love 1
Really 2
I am unsure how to even get started. How do you load text files into bash? And how do you put things? Sorry for the very beginner questions but I would really appreciate some help, thanks!
You can do what you want by this way:
Take the input text file
Take the input Directory to save a file of words in it
Print the unique words with their frequencies.
#!/bin/bash
echo -e "Suggested files: \n"
ls
echo -e "\n"
read -p "Enter the file name :" file
if [ -e $file ]
then
if [ -s $file ]
then
echo -e "Enter the directory where do you want to save the file in \n"
read dir
words=$(grep -v '^$' $file|tr " " "\n"|sort|uniq)
grep -v '^$' $file|tr " " "\n" |sort| grep -v '^$' > $dir/file[$j].sorted
for i in $words
do
num=$(grep -c "$i" $dir/file[$j].sorted)
echo -e "The word \e[1;33m$i\e[0m exists \e[1;34m$num\e[0m times in the file \n"
done
else
echo "The file you have entered is empty"
fi
else
echo "The file you have entered does not exist"
fi
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a file with contents like this
adv_dir=2
ami_pro=3
I have a variable $TEMP with value ami_pro, I want to increase the value of $TEMP by 1.
Want a bash script for this.
State of file after updates
adv_dir=2
ami_pro=4
Icky-ish, spooky indirection, but...
$: echo $TEMP
ami_pro
$: echo $ami_pro
4
$: (($TEMP++)) # $TEMP evals to ami_pro, which gets incremented
$: echo $TEMP
ami_pro
$: echo $ami_pro
5
$: let $TEMP++ # same, likely in any arithmetic context
$: echo $ami_pro
6
so...
TEMP=ami_pro # just setting in the env
grep "$TEMP=" file > $TEMP.tmp # grap the line we need to edit
. $TEMP.tmp # souce it to set the var
sed -i "s/$TEMP=${!TEMP}/$TEMP=$((++$TEMP))/" file # in-place edit
You could skip the tempfile with eval "$(grep "$TEMP=" file)" but eval makes me itch.
The sed is an in-place edit of file using double-quotes to allow the OS to pre-process the vars before making the update.
TEMP=ami_pro
so
$TEMP=${!TEMP}
is parsed by the OS into
ami_pro=$ami_pro
Since we sources the line that said ami_pro=3, that gets further parsed into
ami_pro=3
then
$TEMP=$((++$TEMP))
becomes ami_pro=$((++ami_pro)) which processes to
ami_pro=4
all sed gets is the result strings, so by the time sed starts parsing, what it sees is
s/ami_pro=3/ami_pro=4/
Once that edit is handled, we can break out of the loop.
You can use awk for that:
#!/bin/bash
TMP_FILE=$(mktemp)
awk -F= "/^${TEMP}=/ {print \$1 \"=\" \$2 + 1 \"*\"; next} 1" "${1}" > ${TMP_FILE} && mv ${TMP_FILE} "${1}"
rm ${TMP_FILE}
Pass the file with the data as a parameter to this script.
This question already has answers here:
Forcing bash to expand variables in a string loaded from a file
(13 answers)
Closed 3 years ago.
I have a little script that reads a json file:
{
"path": "$HOME/Projects:$HOME/Github"
}
I want to read path value, split on colon : and then read out the two paths with $HOME expanded.
#!/bin/sh
path_list="$(jq -r '.path' < "$JSON_FILE" | tr ':' '\n')"
echo "$path_list" | while IFS= read -r line; do
echo "$line"
done;
The output is not what I would expect:
$HOME/Projects
$HOME/Github
Yet when I run echo "$HOME/Projects" the $HOME parameter expands fine.
Initially, I thought that I needed double quotes around the variable so I tried echo "\"${line}\"" and that just prints "$HOME/projects". I am confused. Can anyone please shed some light on this for me or point to a good tutorial on bash parameter expansion?
Regarding another SO question addressing similar issue. I do not think this is the same because that OP was asking about expanding strings loaded from a file. I do not think that is the dominant concern in my question. Other responses to this question involve using eval which I would like to because users will be entering their own inputs. Other solutions rely on external packages like gettext. I believe there should be a straight forward answer here.
Solved by adding 'eval':
#!/bin/sh
path_list="$(jq -r '.path' < "$JSON_FILE" | tr ':' '\n')"
echo "$path_list" | while IFS= read -r line; do
eval echo "$line"
done;
More info: https://unix.stackexchange.com/questions/23111/what-is-the-eval-command-in-bash
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Unix for loop help please?
I am trying to list the names of all the files in a directory separated by a blank line. I was using a for loop but after trying a few examples, none really work by adding blank lines in between. Any ideas?
Is there any command which outputs only the first line of a file in unix? How could I only display the first line?
for i in ls
do
echo "\n" && ls -l
done
for i in ls
do
echo "\n"
ls
done
Use head or sed 1q to display only the first line of a file. But in this case, if I'm understanding you correctly, you want to capture and modify the output of ls.
ls -l | while read f; do
printf '%s\n\n' "$f"
# alternately
echo "$f"; echo
done
IFS="
"
for i in $(ls /dir/name/here/or/not)
do
echo -e "$i\n"
done
To see the first part of a file use head and for the end of a file use tail (of course). The command head -n 1 filename will display the first line. Use man head to get more options. (I know how that sounds).
Use shell expansion instead of ls to list files.
for file in *
do
echo "$file"
echo
if [ -f "$file" ];then
read firstline < "$file"
echo "$firstline" # read first line
fi
done