I refer to the following articles for installing SnowAlert.
https://datumstudio.jp/blog/1215_snowflake_17/
I pasted the cat command as shown below and pressed the Enter key, but it doesn't run.
"First, copy and paste the cat command output during the installation into your terminal to create the snowalert- .envs file."
Do you know the cause?
So I assume you are meaning this section:
cat <<END_OF_FILE > snowalert-<account>.envs
SNOWFLAKE_ACCOUNT=<account>
SA_USER=snowalert
SA_ROLE=snowalert
SA_DATABASE=snowalert
SA_WAREHOUSE=snowalert
REGION=<region>.<provider>
PRIVATE_KEY=XXXXXXXXXX
PRIVATE_KEY_PASSWORD=<key_passphase>
END_OF_FILE
Which is not Windows valid commands. I don't have docker or linux on this PC, but using gitBash (MINGW64) I can run that with substitutions just fine:
Simeon#Simeon2 MINGW64 ~
$
if I paste this block
cat <<END_OF_FILE > snowalert-account_name.envs
SNOWFLAKE_ACCOUNT=account_name
SA_USER=snowalert
SA_ROLE=snowalert
SA_DATABASE=snowalert
SA_WAREHOUSE=snowalert
REGION=region.provider
PRIVATE_KEY=XXXXXXXXXX
PRIVATE_KEY_PASSWORD=key_passphase
END_OF_FILE
it is accepted:
Simeon#Simeon2 MINGW64 ~
$ cat <<END_OF_FILE > snowalert-account_name.envs
> SNOWFLAKE_ACCOUNT=account_name
> SA_USER=snowalert
> SA_ROLE=snowalert
> SA_DATABASE=snowalert
> SA_WAREHOUSE=snowalert
> REGION=region.provider
> PRIVATE_KEY=XXXXXXXXXX
> PRIVATE_KEY_PASSWORD=key_passphase
> END_OF_FILE
Simeon#Simeon2 MINGW64 ~
and if I cat that file:
$ cat snowalert-account_name.envs
I get back
SNOWFLAKE_ACCOUNT=account_name
SA_USER=snowalert
SA_ROLE=snowalert
SA_DATABASE=snowalert
SA_WAREHOUSE=snowalert
REGION=region.provider
PRIVATE_KEY=XXXXXXXXXX
PRIVATE_KEY_PASSWORD=key_passphase
so <account>, <region>, <provider>, and <key_passphase> all have to be replaced with correct values that have no <,> values in them, into a bash shell.
OR you can just open the file with any file editor and put the same valid context in.
Related
I want to cat the lines of a csv file using "cat ~/Desktop/file.csv" in a loop using an input user path and when I execute this command in the terminal it works but not with the loop.
When I execute this script it works perfect :
for line in $(cat ~/Desktop/file.csv);
do echo $line;
done
I execute a small script in my desk by clicking on an icon : algo.command and I enter this path : ~/Desktop/file.csv
my script is :
read -p "Enter the path of your file :" path
for line in $(cat "$path");
do echo $line;
done
and I have this output :
cat: ~/Desktop/file.csv: No such file or directory
[Process completed]
Thank you for your help
The ~ is not replaced by /home/<your login name> as you expected because you read a string and you get it as it is, the shell does not interpret it like in your working case.
You have to give the path without using ~ except if you do the substitution in the script by yourself :
If your script is executed by bash :
read -p "Enter the path of your file :" path
if [ ${path:0:2} = "~/" ]
then
path=${path/\~/$HOME}
elif [ ${path:0:1} = "~" ]
then
# suppose ~<user name>
path=${path/\~/\/home\/}
fi
for line in $(cat "$path");
do echo $line;
done
Example having that script in /tmp/s
pi#raspberrypi:/tmp $ echo ~
/home/pi
pi#raspberrypi:/tmp $ (echo aze ; echo qsd) > ~/aze
pi#raspberrypi:/tmp $ cat ~/aze
aze
qsd
pi#raspberrypi:/tmp $ bash s
Enter the path of your file :~/aze
aze
qsd
pi#raspberrypi:/tmp $ bash s
Enter the path of your file :~pi/aze
aze
qsd
pi#raspberrypi:/tmp $ cd
pi#raspberrypi:~ $ bash /tmp/s
Enter the path of your file :aze
aze
qsd
pi#raspberrypi:~ $
I was trying to write a script which involved printing an array with a delimiter. Unfortunately, the printf command that worked typing into the command line did not work when run as a script. It also seems that bash and zsh handle things differently.
This gives the intended output, it works if I just paste directly into the terminal like this:
➜ ~ array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\n' "${array[#]}"
echo "$tmp"
a
b
c
d
However, when run as a script, the output was not what I wanted:
➜ ~ echo 'array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\n' "${array[#]}"
echo "$tmp"' > test1.sh
➜ ~ bash test1.sh
abcdn
Then I remembered that zsh is my default shell, so I tried running it explicitly with zsh. The results were closer to what I wanted (there was something in between each array element), but still not what I got when pasting into the terminal. Why is the \ in \n ignored in this case?
➜ ~ zsh test1.sh
anbncndn
Also, is there a handy table somewhere of the key differences in basic commands like echo and printf between shells and in scripts vs the terminal?
EDIT:
I noticed that my example was flawed in that when I created the script test.sh file, the echo left out the backslash before the n.
➜ ~ echo '
array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\n' "${array[#]}"
echo "$tmp"
'
array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp %sn "${array[#]}"
echo "$tmp"
But what threw me off was that zsh -c showed the same behavior. Is it also stripping out backslashes?
➜ ~ zsh -c 'array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\n' "${array[#]}"
echo "$tmp"'
anbncndn
Edit 2: It's that escape characters work in each of these situations.
three preceding backslashes turn in back into a good ol' newline.
zsh -c 'array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\\\\n' "${array[#]}"
echo "$tmp"'
a
b
c
d
EDIT3: So the escaping in a script works differently from '-c'
The script:
#!/bin/zsh
array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\\n' "${array[#]}"
echo "$tmp"
the result:
➜ ~ zsh test.sh
a
b
c
d
zsh handles arrays differently than bash. In zsh (your interactive shell), array+=b really does append the string b as a new array element.
In bash, however, the same command only appends the string b to the first element of the array; to append a new element, you need to use array+=(b).
zsh -c 'array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '%s\n' "${array[#]}"
echo "$tmp"'
anbncndn
In this, the argument to -c is split into three parts:
'array=()
array+=a
array+=b
array+=c
array+=d
printf -v tmp '
%s\n
and
' "${array[#]}"
echo "$tmp"'
which are all concatenated together. The sections inside single quotes aren't subject to substitutions, expansions, special handling of backslashes, etc. The middle section is, and becomes %sn before it's passed to zsh for execution. When you add extra backslashes, %s\\\\n becomes %s\\n, and the double backslash is turned into a single one by the zsh executing the command.
In your script, because you're not trying to quote the entire thing to make it a single argument, printf -v tmp '%s\\n' "${array[#]}" is split and treated the way you want. However, because you're doubling up the backslash there, $tmp is set to a\nb\nc\nd\n. Then when you echo it, the default zsh behavior is to expand backslash escape sequences in the string being printed, so it looks right. This can be disabled with the BSD_ECHO shell option, or using echo -E. If you want actual newlines, use a single backslash inside single quotes, or a double one inside double quotes or unquoted.
Demonstration:
$ printf -v tmp '%s\\n' a b c d
$ echo "$tmp"
a
b
c
d
$ echo -E "$tmp"
a\nb\nc\nd\n
$ setopt BSD_ECHO
$ echo "$tmp"
a\nb\nc\nd\n
$ printf -v tmp '%s\n' a b c d
$ echo "$tmp"
a
b
c
d
I've already read a lot of questions concerning reading and writing in ARRAY in bash. I could not find the solution to my issue.
Actually, I've got a file that contains the path of a lot of files.
cat MyFile
> ~/toto/file1.txt
> ~/toto/file2.txt
> ~/toto/file3.txt
> ~/toto/file4.txt
> ~/toto/file5.txt
I fill an array ARRAY to contain this list:
readarray ARRAY < MyFile.txt
or
while IFS= read -r line
do
printf 'TOTO %s\n' "$line"
ARRAY+=("${line}")
done <MyFile.txt
or
for line in $(cat ${MyFile.txt}) ;
do echo "==> $line";
ARRAY+=($line) ;
done
All those methods work well to fill the ARRAY,
echo "0: ${ARRAY[1]}"
echo "1: ${ARRAY[2]}"
> 0: ~/toto/file1.txt
> 1: ~/toto/file2.txt
This is awesome.
but my problem is that if I try to diff the content of the file it does not work, it looks like the it does not expand the content of the file
diff ${ARRAY[1]} ${ARRAY[2]}
diff: ~/toto/file1.txt: No such file or directory
diff: ~/toto/file2.txt: No such file or directory
but when a print the content:
echo diff ${ARRAY[1]} ${ARRAY[2]}
diff ~/toto/file1.txt ~/toto/file2.txt
and execute it I get the expected diff in the file
diff ~/toto/file1.txt ~/toto/file2.txt
3c3
< Param = {'AAA', 'BBB'}
---
> Param = {'AAA', 'CCC'}
whereas if I fill ARRAY manually this way:
ARRAY=(~/toto/file1.txt ~/toto/file2.txt)
diff works well.
Does anyone have an idea?
Thanks a lot
Regards,
Thomas
Tilde expansion does not happen when you use variable substitution from ${ARRAY[index]}.
Put the full path to the files in MyFile.txt and run your code again.
I want to print a line if a statement is true, but I want to loop through several variations. This is works as a batch script:
Awk "($9==1) {print $0}" file > out.txt & type out.txt >> all_out.txt
Awk "($9==3) {print $0}" file > out.txt & type out.txt >> all_out.txt
Awk "($9==5) {print $0}" file > out.txt & type out.txt >> all_out.txt
But not very elegant. Can this be written into a for loop or if statement? I'm using gnuawk on windows with cygwin installed.
Any help would be greatly appreciated.
try:
awk '($9==1) || ($9==3) || ($9==5)' Input_file > all_out.txt
OR
awk '($9%2 != 0)' Input_file > all_out.txt
Considering that you want to take all conditions output into a single file here, let me know if this is not the case.
Try this -
$ awk '($9 ~ /^1$|^3$|^5$/) {print $0}' file
I am reading in a small csv file in the format size,name - one set per line. For my testing file I have two lines in the csv file.
If I use the code
while
IFS=',' read -r size name
do
printf "%s\n" "name"
done < temp1.txt
The name values for each of the lines is printed to the terminal.
If I use the code
while
IFS=',' read -r size name
do
printf "%s\n" "name" > temp2.txt
done < temp1.txt
Then only the last name is printed to the temp2.txt file.
What am I doing wrong?!
You are using >, so that the file gets truncated every time. Instead, use >> to append:
So it should be like this:
printf "%s\n" "name" >> temp2.txt
^^
All together:
while
IFS=',' read -r size name
do
printf "%s\n" "name" >> temp2.txt
done < temp1.txt
Basic example:
$ echo "hello" > a
$ echo "bye" > a
$ cat a
bye # just last line gets written
$ echo "hello" >> a
$ echo "bye" >> a
$ cat a
hello
bye # everything gets written