What I'm trying to do
I'm trying to apply a substitution with sed on an output of the rust compiler.
Small example
Do cargo new test.
src/main.rs
fn main() {
println("Println is a macro!!");
}
Now do cargo run | sed -n -e 's/help/Help/'.
Expected output
error[E0423]: expected function, found macro `println`
--> src/main.rs:2:5
|
2 | println("Println is a macro!!");
| ^^^^^^^ not a function
|
Help: use `!` to invoke the macro
|
2 | println!("Println is a macro!!");
| +
For more information about this error, try `rustc --explain E0423`.
error: could not compile `rust_tmp` due to previous error
What I get
error[E0423]: expected function, found macro `println`
--> src/main.rs:2:5
|
2 | println("Println is a macro!!");
| ^^^^^^^ not a function
|
help: use `!` to invoke the macro
|
2 | println!("Println is a macro!!");
| +
For more information about this error, try `rustc --explain E0423`.
error: could not compile `rust_tmp` due to previous error
(nothing has changed)
What else I tried
I also tried:
cargo run 2>&1 sed -n -e 's/help/Help/'
Try piping stderr instead of stdout to sed: cargo run 3>&1 1>&2 2>&3 | sed -n -e 's/help/Help/'.
You can also pipe both stderr & stdout to sed: cargo run |& sed -n -e 's/help/Help/'.
Have a look at the bash manual chapter on redirections.
Related
I have command in my xubuntu:
nvidia-settings -q gpucoretemp | grep '(user-xubuntu:0.0):' | sed 's/^.*: //'
And I have the result:
libEGL warning: DRI2: failed to authenticate
46.
If I try to exclude 'libEGL warning: DRI2: failed to authenticate' :
nvidia-settings -q gpucoretemp | grep -v 'libEGL warning: DRI2: failed to authenticate' | grep '(user-xubuntu:0.0):' | sed 's/^.*: //'
The result is the same. How to ignore the 'libEGL warning: DRI2: failed to authenticate' string?
You can first redirect stderr to stdout and then filter the result with grep.
nvidia-settings -q gpucoretemp 2>&1 | grep -v 'libEGL warning: DRI2: failed to authenticate' | grep '(user-xubuntu:0.0):' | sed 's/^.*: //'
I have some trouble with the redirection stuff in Linux,
here a small schematic to illustrate the goal, better than words (I hope)
+------------+ +----------------+
| std_out +----------+------------------>+ log.log |
+------------+ | +----------------+
|
| +----------------+
+----------------->>+ |
| histo.log |
+----------------->>+ |
| +----------------+
|
|
+------------+ | grep -v "exp" +----------------+
| std_err +---------+------------------>+ error.log |
+------------+ +----------------+
I would like to do this with the output of the script.
I succeed to do the log.log and the error.log with the grep,
./script.sh >log.log 2> >(grep -v "Expression" > error.log )
But I'm in trouble with histo.log where it should add (i mean >> or tee -a not >) std_out and the std_err (without the grep) and I don't really understand the advanced stuff about redirection.
If anyone have an idea to solve my problem, I will be thankfull :)
Here's a scary looking use of output process substititions:
$ cat driver.sh
echo line 1 to stdout
echo line 1 to stderr >&2
echo line 2 to stderr is expected >&2
echo line 3 to stderr >&2
$ sh driver.sh > >(tee -a histo.log > log.log) 2> >(tee -a histo.log | grep -v exp > error.log)
$ cat log.log
line 1 to stdout
$ cat histo.log
line 1 to stdout
line 1 to stderr
line 2 to stderr is expected
line 3 to stderr
$ cat error.log
line 1 to stderr
line 3 to stderr
This will append to histo.log, but overwrite the log.log and error.log files, as you indicated in your diagram.
I am trying to write a batch file/shell script that reads the contents of a file, matches those contents with a directory structure and invokes an executable file.
Let's say there is a sequence.txt file in /system/ directory. The sequence file is to represent or force the order of execution. This is important
The sequence.txt file has following enteries:
1;schema1;procedures
1;schema1;functions
2;schema2;procedures
2;schema2;functions
........
and then there is a directory, and the directory has following subdirs
/scripts
| +--/schema1
| | +--/procedures
| | | --1.sql
| | | --2.sql
| | +--/functions
| | | --1.sql
| | | --2.sql
| | +--/packages
| | | --1.sql
| | | --2.sql
| | +--/logs
| +--/schema2
| | +--/procedures
| | | --1.sql
| | | --2.sql
| | +--/functions
| | | --1.sql
| | | --2.sql
| | +--/packages
| | | --1.sql
| | | --2.sql
| | +--/logs
.......
........
Now I would like to run flyway (a database migration software) in a loop using this way:
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
So far this is my progress:
#!/bin/bash
while read i;
do echo "$i";
done < ./system/sequence.txt
How can I proceed further? I know that this kind of scripting involves variables and then loops but I can't find a way to translate it into technical level.
Cheers and thanks in advance! :-)
Though not completely clear about what you want, here is some inspiration:
while read line; do
OIFS=$IFS
IFS=';'
a=()
for name in ${line}; do
a+=(${name})
done
IFS=$OIFS
number=${a[0]}
schema=${a[1]}
subdir=${a[2]}
echo "Flyway -schema=${schema} -locations=/scripts/${schema}/procedures, /scripts/${schema}/functions, /scripts/${schema}/packages migrate -x | tee /scripts/${schema}/log/logfile_ddmmyy.log"
done <<EOF
1;schema1;procedures
1;schema1;functions
2;schema2;procedures
2;schema2;functions
EOF
It doesn't exexute Flymake, it just echo the Flymake commands.
It uses the special variable $IFS to do the magic.
Fit it to your needs.
output
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema1 -locations=/scripts/schema1/procedures, /scripts/schema1/functions, /scripts/schema1/packages migrate -x | tee /scripts/schema1/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
Flyway -schema=schema2 -locations=/scripts/schema2/procedures, /scripts/schema2/functions, /scripts/schema2/packages migrate -x | tee /scripts/schema2/log/logfile_ddmmyy.log
I am not sure about the exact relation betwen values and final command path but awk is the tool to construct the call. Use somethin like:
c = `echo $i | awk -F ";" '{print "flyway" $1 "_" $2}'
where $x is the position of the value and you can construct a string.
After that you can run the c var with
`echo $c`
That should work.
UPDATED:
If I understand correctly what you need, you have to set two whiles, one inside the other. Something like this:
cat tt.txt | awk -F";" '{print $1}'| sort -u | while read i
do
sc = `grep $i tt.txt | head -n 1 | awk -F";" '{print $2}'`
pt1 = "Flyway -schema=" $sc " -locations="
pt3 = " -x | tee /scripts/" $sc "/log/logfile_ddmmyy.log"
grep $i tt.txt | while read j
do
c=`echo $j | awk -F";" '{print $2}'| sort -u`
pt2 = $pt2 "/scripts/" $sc "/" $c ""
done
echo $pt1 $pt2 $pt3
done
I get the following error:
> echo "${$(qstat -a | grep kig):0:7}"
-bash: ${$(qstat -a | grep kig):0:7}: bad substitution
I'm trying to take the number before. of
> qstat -a | grep kig
1192530.perceus- kigumen lr_regul pbs.sh 27198 2 16 -- 24:00:00 R 00:32:23
and use it as an argument to qdel in openPBS so that I can delete all process that I started with my login kigumen
so ideally, this should work:
qdel ${$(qstat -a | grep kig):0:7}
so far, only this works:
str=$(qstat -a | grep kig); qdel "${str:0:7}"
but I want a clean one-liner without a temporary variable.
The shell substring construct you're using (:0:7) only works on variables, not command substitution. If you want to do this in a single operation, you'll need to trim the string as part of the pipeline, something like one of these:
echo "$(qstat -a | grep kig | sed 's/[.].*//')"
echo "$(qstat -a | awk -F. '/kig/ {print $1}')"
echo "$(qstat -a | awk '/kig/ {print substr($0, 1, 7)}')"
(Note that the first two print everything before the first ".", while the last prints the first 7 characters.) I don't know that any of them are particularly cleaner, but they do it without a temp variable...
qstat -u palle | cut -f 1 -d "." | xargs qdel
Kills all my jobs... normally I grep out the jobname(s) before cut'ing...
So I use a small script "idlist":
qstat -u palle | grep -E "*.in" | grep -E "$1" | cut -f 1 -d "." | xargs
To see all my "map_..." jobs:
idlist "map_*"
For killing all my "map_...." jobs:
idlist "map_*" | xargs qdel
yet another ways :
foreach m1 in $(qstat -a );do
if [[ $m1 =~ kig ]];then
m2=${m1%.kig}
echo "kig found $m2 "
break
fi
done
I want to use MPC (CLI interface to MPD) but unfortunately to me it does not accept piping.
So something like:
ll | grep "pattern" | sed 's/this/that/' | mpc
does not work for me, nor
ll | grep "pattern" | sed 's/this/that/' | mpc -
This
MPCTMP=`ll | grep "pattern" | sed 's/this/that/'` && echo $MPCTMP
works as expected, but this:
MPCTMP=`ll | grep "pattern" | sed 's/this/that/'` && mpc $MPCTMP
does not return results, variable is not understood but this program
I'm new to Linux and could not find anything searching with Google
Thanks
Try xargs
ll | grep "pattern" | sed 's/this/that/' | xargs mpc