In bash/ Ubuntu,
If there is a ASCII art file: "ascii-art" in the following
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client ${CLIENT_ID}
Is there anyway to pass the variable "${CLIENT_ID}" into the ascii-art every time we call it?
The way we call it at the moment:
cat ascii-art
The following ways don't work
1. cat ascii-art | CLIENT_ID="1"
or
Add one more line in the first line of the file "ascii-art"
. command_line_parse.sh -c ${CLIENT_ID}
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client ${CLIENT_ID}
Then
cat ascii-art | CLIENT_ID="1"
Could any guru enlighten? Thanks.
The envsubst tool is written for exactly this purpose:
CLIENT_ID=foo envsubst ascii-art
This is a preferable tool to sed, which restricts the range of possible values (if you had a / in your id, or even worse a semicolon followed by another sed command, serious bugs could ensue).
See also TemplateFiles on the Wooledge wiki, which includes a native-bash implementation for systems without GNU gettext (which includes envsubst).
The following evaluates the echo command for the contents of the file:
CLIENT_ID=1000 eval "$(cat <<EOC
echo -e "$(<ascii-art)"
EOC
)"
CLIENT_ID=1000 assigns environment variable for the eval command
eval accepts a here document as its single argument
$(<ascii-art), in Bash, does the same as $(cat ascii-art)
EDIT regarding the scary eval
It's true that we should avoid using eval. But we should also understand the
purpose of the command and do use it when appropriate. We should understand
the security risks, and decide whether we should, or we shouldn't use eval
in certain situations.
The Bash Hackers Wiki gives a good description
of eval:
Perhaps the easiest way to think about eval is that it works in the same way
as running bash -c "bash codeā¦" from a script, except in the case of
eval, the given code is executed in the current shell environment rather
than a child process.
So eval just executes the shell code we pass. How often we execute
external commands from Bash scripts? I guess, quite often. And the commands
are just trusted executables which may well be Bash scripts themselves.
Then why should one be scared of evaluating some echo "trusted content"?
It is up to the user(OP) to decide whether it is safe to use eval in certain
situation. However, this answer definitely gives him an option; it is an
alternate solution. So I don't understand the downvote on this answer.
First: look at the programs figlet, toilet or cowasy. These are probably finished implementation of what you want.
If you want to write it yourself:
sed 's/${CLIENT_ID}/42/g' ascii-art
Modified from RotatingPieces' answer above
First modify the "ascii-art" file, and change "${CLIENT_ID}" into "CLIENT_ID_ART"
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client CLIENT_ID_ART
Now the following approach might not be very elegant, but it works perfectly
CLIENT_ID="1" # The ${CLIENT_ID} will actually be from the command line parser
echo "sed 's/CLIENT_ID_ART/"${CLIENT_ID}"/g' ascii-art > call_art
chmod +x call_art
./call_art &
rm -f call_art
The above will print out the following in the output
|__ __| ____|/ ____|__ __|
| | | |__ | (___ | |
| | | __| \___ \ | |
| | | |____ ____) | | |
|_| |______|_____/ |_| Client 1
Related
I want to write to a file in bash but I wan to use a specific font size. For example, I want to write to the file hello but with a font size of 30.
echo "Hello "
Also, is there another way to indent in bash when writing to a file besides using spaces like below?
echo " Hello"
As #thatotherguy commented, details like fonts are determined by the program reading the file, so it depends on what sort of file you're creating, and you'll typically use different tools to create different types of files. echo and other shell commands just work with text; the literal characters h, e, l, l, and o are sent to the terminal, no size or font data goes along with it.
If you're trying to simply make big font in your terminal there are tricks, like ASCII art text using figlet:
$ figlet "Hello"
_ _ _ _
| | | | ___| | | ___
| |_| |/ _ \ | |/ _ \
| _ | __/ | | (_) |
|_| |_|\___|_|_|\___/
And since you asked about indentation, notice that figlet supports centered text and other sorts of formatting:
figlet -c "Hello"
_ _ _ _
| | | | ___| | | ___
| |_| |/ _ \ | |/ _ \
| _ | __/ | | (_) |
|_| |_|\___|_|_|\___/
It is possible to make some changes to the text that gets displayed in your terminal (you've probably seen colored text before from some commands), but not fonts. You can use tput to modify the text you output, e.g. with colors or bold, but not size or font (which are configured by your terminal itself). Some examples of that in this question, but tput is easier than figuring out all the \e... escape sequences they're talking about.
# it looks plain here, but if you run this in your shell it ought to be underlined
$ echo "$(tput smul)hello$(tput rmul)"
hello
If ASCII art or the color/font features most terminals support isn't what you're looking for, you'll need to share more details about what you're trying to do.
$ cat urls.txt
/var/www/example.com.com/upload/email/email-inliner.html
/var/www/example.com.com/upload/email/email.html
/var/www/example.com.com/upload/email/email2-inliner.html
/var/www/example.com.com/upload/email/email2.html
/var/www/example.com.com/upload/email/AquaTrainingBag.png
/var/www/example.com.com/upload/email/fitex/fitex-ecr7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ect7.jpg
/var/www/example.com.com/upload/email/fitex/fitex-ecu7.jpg
/var/www/example.com.com/upload/email/fitex/fitex.html
/var/www/example.com.com/upload/email/fitex/logo.png
/var/www/example.com.com/upload/email/fitex/form.html
/var/www/example.com.com/upload/email/fitex/fitex.txt
/var/www/example.com.com/upload/email/bigsale.html
/var/www/example.com.com/upload/email/logo.png
/var/www/example.com.com/upload/email/bigsale.png
/var/www/example.com.com/upload/email/bigsale-shop.html
/var/www/example.com.com/upload/email/bigsale.txt
Can anyone help me to get dirname for this?
dirname /var/www/example.com.com/upload/email/sss.png works fine, but what about a list of URLs?
Is it possible to achieve this without the use of any form of a loop (for or while). As the number of URLs can be more than several tens of millions. The best way would be with the help of redirection (tee) to a file
As always when it boils down to things like this, Awk comes to the rescue:
awk 'BEGIN{FS=OFS="/"}{NF--}1' <file>
Be aware that this is an extremely simplified version of dirname and does not have the complete identical implementation as dirname, but it will work for most cases. A correct version, which covers all cases is:
awk 'BEGIN{FS=OFS="/"}{gsub("/+","/")}
{s=$0~/^\//;NF-=$NF?1:2;$0=$0?$0:(s?"/":".")};1' <file>
The following table shows the difference:
| path | dirname | awk full | awk short |
|------------+---------+----------+-----------|
| . | . | . | |
| / | / | / | |
| foo | . | . | |
| foo/ | . | . | foo |
| foo/bar | foo | foo | foo |
| foo/bar/ | foo | foo | foo/bar |
| /foo | / | / | |
| /foo/ | / | / | /foo |
| /foo/bar | /foo | /foo | /foo |
| /foo/bar/ | /foo | /foo | /foo/bar |
| /foo///bar | /foo | /foo | /foo// |
note: various alternative solutions can be found in Extracting directory name from an absolute path using sed or awk. The solutions of Kent will all work, the solution of Solid Kim just needs a tiny tweak to fix the multiple slashes (and misses upvotes!)
i dont see why it isnt working.
if you could help me with this it would be greatly appreciated.
i run the file and it just exits out, as if the code is missing.
cls
echo //========================================//
echo \\ --- --- ---------- ---------- \\
echo // | \ | | | | | | //
echo \\ | \ \ | | -- -- -- -- \\
echo // | |\ \| | | | | | //
echo \\ | | \ | | | | | \\
echo // |__| \____| |__| |__| //
echo \\========================================\\
echo press any key to begin
pause
You need to escape the pipes | with a carret (^|).
However you should store ascii art in a txt file and use type my_banner.txt in order to display it. This is easier ...
In a project where XML/JS/Java files can contain references to other such files, I'd like to be able to have a quick overview of what has to be carefully checked, when one file has been updated.
So, it means I need to eventually have a look at all files referencing the modified one, and all files referencing files which refer to the modified one, etc. (recursively on matched files).
For one level, it's quite simple:
grep -E -l -o --include=*.{xml,js,java} -r "$FILE" . | xargs -n 1 basename
But how can I automate that to match (grand-(grand-))parents?
And how can that be, maybe, made more readable? For example, with a tree structure?
For example, if the file that interests me is called modified.js...
show-referring-files-to modified.js
... I could wish such an output:
some-file-with-ref-to-modified.xml
|__ a-file-referring-to-some-file-with-ref-to-modified.js
another-one-with-ref-to-modified.xml
|__ a-file-referring-to-another-one-with-ref-to-modified.js
|__ a-grand-parent-file-having-ref-to-ref-file.xml
|__ another-file-referring-to-another-one-with-ref-to-modified.js
or any other output (even flat) which allows for quickly checking which files are potentially impacted by a change.
UPDATE -- Results of current proposed answer:
ahmsff.js
|__ahmsff.xml
| |__ahmsd.js
| | |__ahmsd.xml
| | | |__ahmst.xml
| | | | |__BESH.java
| |__ahru.js
| | |__ahru.xml
| | | |__ahrut.xml
| | | | |__ashrba.js
| | | | | |__ashrba.xml
| | | | | | |__STR.java
| | |__ahrufrp.xml
| | | |__ahru.js
| | | | |__ahru.xml
| | | | | |__ahrut.xml
| | | | | | |__ashrba.js
| | | | | | | |__ashrba.xml
| | | | | | | | |__STR.java
| | | | |__ahrufrp.xml
| | | | | |__ahru.js
| | | | | | |__ahru.xml
| | | | | | | |__ahrut.xml
| | | | | | | | |__ashrba.js
| | | | | | | | | |__ashrba.xml
| | | | | | | | | | |__STR.java
| | | | | | |__ahrufrp.xml
(...)
I'd use a shell function (for the recursion) inside an shell script:
Assuming the filenames are unique have no characters that need escaping in them:
File: /usr/local/bin/show-referring-files-to
#!/bin/sh
get_references() {
grep -F -l --include=*.{xml,js,java} -r "$1" . | grep -v "$3" | while read -r subfile; do
#read each line of the grep result into the variable subfile
subfile="$(basename "$subfile")"
echo "$2""$subfile"
get_references "$subfile" ' '"$2" "$3"'\|'"$subfile"
done
}
while test $# -gt 0; do
#loop so more than one file can be given as argument to this script
echo "$1"
get_references "$1" '|__' "$1"
shift
done
There still are lots of performance enhancements possible.
Edit: Added $3 to prevent infinite-loop.
I have a logo which I want to print/echo using bash in console, through scripts, but I can't even paste here properly(looks good inside .txt file):
___ _____ _ _ _____ _ _ ___
| _| / ___| | | || ___| \ | | |_ |
| | \ `--.| |_| || |__ | \| | | |
| | `--. \ _ || __|| . | | |
| | /\__/ / | | || |___| |\ | | |
| |_ \____/\_| |_/\____/\_| \_/ _| |
|___| |___|
How I can do that properly and make it colour without 3rd party extensions?
Also, is it possible to print it from the file?
You may use tput:
tput setaf 2; cat logo.txt
2 is the color code here (red). These are the available codes:
Value Color
0 Black
1 Red
2 Green
3 Yellow
4 Blue
5 Magenta
6 Cyan
7 White
8 Not used
9 Reset to default color