Escaping bash variable [closed] - linux

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 3 years ago.
Improve this question
I'm a bit stuck with this. I'm delaring a variable at the top of my script, then I am creating a file as part of my script:
app="testing"
cat <<EOF >/etc/init.d/test
#!/bin/bash
args="--emperor $APPCONF/test/$APP.ini"
EOF
It doesn't seem to work though, it seems on the $app variable. Must I do something to this variable to get it to display it's value, "testing" inside the file I create?

Use consistent case. variable names are case sensitive.

Let's say you were doing this the Right Way. You'd want to store your data in an array:
args=( --emperor "${appconf}/test/${app}.ini" )
and then convert it to a string for embedding:
printf -v args_str '%q ' "${args[#]}"`
...and use that string inside your heredoc:
#!/bin/bash
args=( $args_str )
EOF
...beyond which, anything inside the script being created would want to expand it as an array:
run_something "${args[#]}"
See BashFAQ #50 for rationale and details.

Besides using consistent case ($app is different from $APP), you may want to enclose your variable names within brackets - you may get issues if you use spaces in between your variables values otherwise, and it's considered a good practice. For example:
args="--emperor ${APPCONF}/test/${APP}.ini"
That way, $APPCONF does not get confused with ${APP}CONF also. I hope this helps!

I'm not sure to understand your question. I suppose that you would like to end with a file
/etc/init.d/test
containing the text:
#!/bin/bash
args="--emperor $APPCONF/test/testing.ini"
if so your script should be:
app="testing"
cat <<EOF >/etc/init.d/test
#!/bin/bash
args="--emperor \$APPCONF/test/$app.ini"
EOF

Related

How do I set two different strings equal to each other inside a variable in perl? [closed]

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 last year.
Improve this question
I have some directory paths.
dir1/abc/dir2/dir3
and
dir1/xyz/dir2/dir3
I have a Perl script that manipulates these directories, but that script is running into errors with path names.
How can I set "abc" = "xyz" in a perl variable, so that I can use that variable in the pathnames above?
For example, it should be
dir1/$PathVariable/dir2/dir3
so that the script doesn't care whether part of the path is "abc" or "xyz".
So far, I tried using the eq keyword
my $Path1 = "abc";
my $Path2 = "xyz";
my %PathVariable = $Path1 eq $Path2;
Turns out eq doesn't do what I thought. Any tips?
I think this is your question. You have a path template such as dir1/$PathVariable/dir2/dir3 and you want to fill in the $PathVariable with different values.
The quick way to do that is simple double-quoted interpolation:
my $PathVariable = 'abc';
my $directory = "dir1/$PathVariable/dir2/dir3";
print "Dir is <$directory>\n"; # dir1/abc/dir2/dir3
But, you want to do this for a few directories. Iterate through a list of the values you want. Each time through the foreach, $PathVariable gets the next value from #paths:
my #paths = qw(abc xyz);
foreach my $PathVariable ( #paths ) {
my $directory = "dir1/$PathVariable/dir2/dir3";
print "Dir is <$directory>\n";
... do whatever you need to do ...
}
Now, having figured that part out, there are a few things to think about when creating paths. The File::Spec module that comes with Perl knows how to put together paths appropriate for the system that you are working on. It's a good habit to have so you avoid weird cases:
use File::Spec::Functions;
my $dir = catfile( 'dir1', $PathVariable, 'dir2', 'dir3' );
There are other CPAN modules that do the job too, but that might be a bit much until you solve this issue.

How to put special characters in variable and use them in string?

I'm wondering is there anyway to use for example , or ^ or % and so on, from variables in Bash ?
in instance I have three variables
var1='hello world'
var2=${var1:3}
var3='^'
I want to do this in bash ! please attention to my question I know it's very simple in other ways but how about this ?
echo ${var1:0:3}${var2$var3} # instead of echo ${var1:0:3}${var2^}
and finally output is :
heLlo world
In theory, eval can do execute arbitrary code, but has many security issues, so it should be used as last resort. Use it only when you trust the input 100%.
var1='hello world'
var2=${var1:3}
var3='^'
eval echo '${var1:0:3}${var2'$var3'}'

Is there a way to consolidate similar (but not the same) rows in a text file? [closed]

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 4 years ago.
Improve this question
I have a text file on a linux box that has two columns.
1. An IP address
2. A code for a location
Some IP addresses are listed more than once because more than one code is associated with it.
Example:
140.90.218.62 vaac
140.90.220.11 aawu
140.90.220.11 afc
140.90.220.11 arh
140.90.220.40 afc
I would like to consolidate such IP addresses to only be listed once, just with several location codes
Like this
140.90.218.62 vaac
140.90.220.11 aawu:afc:arh
140.90.220.40 afc
I could always code a for loop to read in the file, consolidate the values into an array, and write the cleaned up version back out.
Before I do that I was wonder if a combination of *nix utilities might do the job, do it with less code, etc.
Using awk
awk '{a[$1]=($1 in a?a[$1]":"$2:$2)}END{for (i in a) print i, a[i]}' file
Output:
140.90.220.11 aawu:afc:arh
140.90.220.40 afc
140.90.218.62 vaac
Explanation:
a[$1]=($1 in a?a[$1]":"$2:$2) - creates an indexed array with the IP address as key. Each $2 with the same IP is concatenated to the current value separated by a colon if ther's already an value.
for (i in a) print i,a[i] - when stdin closes, print all entries in a, the index (IP) first and all the values.
bash version 4, with associative arrays.
declare -A data
while read -r ip value; do
data[$ip]+=":$value"
done < file
for key in "${!data[#]}"; do
printf "%s %s\n" "$key" "${data[$key]#:}"
done
With perl:
perl -lanE 'push #{$ips{$F[0]}}, $F[1]; END { $" = ":"; say "$_ #{$ips{$_}}" for sort keys %ips }' yourfile.txt
outputs
140.90.218.62 vaac
140.90.220.11 aawu:afc:arh
140.90.220.40 afc

How would I make the true results of this awk command issue a command like sendmail etc [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to create a script that checks the 5th value of every line in a CSV output. For instance:
AAA,111,222,333,1
Here is what I am using:
awk -F "," '{if ($5 > 10) print $1 " has a value of " $5}' results
I was missing the "," ... what I was hoping to create is that if the results were in fact greater, True, then I could issue a command like sendmail with the results. if false do nothing.
All you need to do what you say you want is:
awk -F, '{printf "1st-column-value has 5th-column-value %s than 10\n", ($5>10 ? "greater" : "less")}' file
but of course your logic is wrong (consider equal to 10) and idk if you actually wanted the first column value printed instead of just the text 1st-column-value as you state in your question, and so on since you didn't include concise, testable sample input and expected output in your question.

Linux/ unix duplicate names [closed]

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 8 years ago.
Improve this question
What I need to do is, to check for duplicate domain names and find if there is some.
So far I tried many commands with grep, awk ,sort, uniq but couldn't work this out, I am feeling its very simple, but can't reach it.
P.s. If i use uniq -c I get a huge list of string in this file, and I see how many duplicates it has and which by number string it is.
adding 20 rows from the file I am using
1,google.com
2,facebook.com
3,youtube.com
4,yahoo.com
5,baidu.com
6,amazon.com
7,wikipedia.org
8,twitter.com
9,taobao.com
10,qq.com
11,google.co.in
12,live.com
13,sina.com.cn
14,weibo.com
15,linkedin.com
16,yahoo.co.jp
17,tmall.com
18,blogspot.com
19,ebay.com
20,hao123.com
The output I would like to see
> 2 google
> 2 yahoo
Thanks for help !
You could use something like this to get the output you want:
$ awk -F'[.,]' '{++a[$2]}END{for(i in a)if(a[i]>1)print a[i],i}' file
2 google
2 yahoo
With the input field separator to either . or ,, the first {block} is run for every row in the file. It builds up an array a using the second field: "google", "facebook", etc. $2 is the value of the second field, so ++a[$2] increments the value of the array a["google"], a["facebook"], etc. This means that the value in the array increases by one every time the same name is seen.
Once the whole file is processed, the for (i in a) loop runs through all of the keys in the array ("google", "facebook", etc.) and prints those whose value is greater than 1.
Given this file:
$ cat /tmp/test.txt
1,google.com
2,facebook.com
3,youtube.com
4,yahoo.com
5,baidu.com
6,amazon.com
7,wikipedia.org
8,twitter.com
9,taobao.com
10,qq.com
11,google.co.in
12,live.com
13,sina.com.cn
14,weibo.com
15,linkedin.com
16,yahoo.co.jp
17,tmall.com
18,blogspot.com
19,ebay.com
20,hao123.com
In a Perl 1 liner:
$ perl -lane '$count{$1}++ if /^\d+,(\w+)/; END {while (($k, $v) = each %count) { print "$v $k" if $v>1}}' /tmp/test.txt
2 yahoo
2 google

Resources