New answers tagged

0

Parameter Expanion. INPUT="TEST: www.google.com TEST2: 123444 TEST3 Id: ABCD1234 TEST.txt" INPUT="${INPUT% TEST*}" echo "${INPUT##* }" Command Substitution with a Here string and array. INPUT="TEST: www.google.com TEST2: 123444 TEST3 Id: ABCD1234 TEST.txt" OUTPUT=$(read -ra var <<< "$INPUT"; echo "${var[-2]}") echo "$OUTPUT" Awk. INPUT="...


0

You can try this with GNU grep: echo "$INPUT" | grep -Po "(?<=Id:[[:blank:]]).*[[:blank:]]"


0

You didn't say you're limited to sed ... echo "$INPUT" | awk '{print $7}'


0

Here's one way, using a capturing group sed 's/.*TEST3 Id: \(.*\) .*/\1/' Test echo "TEST: www.google.com TEST2: 123444 TEST3 Id: ABCD1234 TEST.txt" | sed 's/.*TEST3 Id: \(.*\) .*/\1/' ABCD1234


0

Try this one: echo "$INPUT" | sed 's/.*TEST3 Id: \([^ ]*\).*/\1/' The \( \) is a useful construct that delimits the part of the regex that will be reproduced by \1. So it reproduces only the largest string without spaces beginning right after TEST3 Id:.


2

In printf, %[number]s prints a string to a fixed-length field number characters wide, filling with space. So %12s produces a 12-character field, or just 12 spaces if the string is empty, like it is here. So printf %${I}s produces as many spaces as the variable I tells, they're then changed to dots. So, if I is, say 4, the other tr gets a first argument of .....


0

There is no .Disconnected key in the JSON response. To check the .mongodb key for the string connected you may do this: #!/bin/sh if wget --timeout 5 -O - -q -t 1 https://www.example.com/healthz | jq --exit-status '.mongodb == "connected"' >/dev/null then # code for the case when MongoDB is connected else # code for the case when MongoDB is *...


2

I put an echo in to it, so that I could see what the 2nd command in the pipeline is. The arguments to this command are constructed with $(). in="MJHVIZN ZPIO YJHPN" for i in $(seq 25); do echo tr $(printf %${i}s | tr ' ' '.')\A-Z A-ZA-Z done After running it should make more sense. Also removed the capitals in variable names. I don't know who is ...


0

You could add set -x to the beginning of /etc/profile, causing the shell to display every command it is going to execute with all the variable expansions etc. already expanded, so you'll see what the shell is actually doing. But if you're talking about a GUI login, first check that your filesystem is not 100% full: creating a GUI session requires creating a ...


3

Try exporting the $1 in your script. #!/usr/bin/env bash pattern=$1 export pattern find . -name '*.pdf' -exec sh -c 'pdftotext "{}" - | grep --with-filename --label="{}" --color "$pattern"' \; But I suggest to rewrite it to #!/usr/bin/env bash pattern=$1 export pattern find . -name '*.pdf' -exec sh -c 'for f; do pdftotext "$f" - | grep --with-...


2

You need to pass parameter $0 as name of the shell for error messages and positional parameter $1 to the sh -c '...' call: #!/bin/bash find . -name '*.pdf' -exec sh -c ' pdftotext "{}" - | grep --with-filename --label="{}" --color "$1" ' sh "$1" \; Here, sh is used as $0 (can be any name) and the original argument "$1" is passed as positional parameter $...


1

This just feels horrible but it works with your data set sed -E "s/^(.+-)(([0-9]+\.){2}[0-9]+-.*)$/\1 \2/g" file1 | sort -r | awk '$1!=old{print $1$2; old=$1}' Split out the base names with sed sort in reverse to bubble the higher versions to the top awk out the first occurrence of each base name, reassembling them as you do. Output: glusterfs-cli-3....


0

You can do that with eval: # usage xfilter filter_spec filter_args... xfilter() { local cmd flt=$1; shift printf -v cmd " >($flt)" "$@" eval "tee $cmd" wait } $ echo paa | xfilter 'sed %q' s/a/e/g s/a/o/g paa pee poo $ tgrep(){ grep "$1" > "./$1"; } $ printf '%s\n' foo bar | xfilter 'tgrep %q' foo bar foo bar $ grep . foo bar foo:foo ...


0

The easiest way is to do them one at a time recursively: filter() { if [ "$#" -eq 0 ] then cat else f="$1" shift tee >(grep "$f" > "$f") | filter "$@" fi } printf '%s\n' {foo,bar}{0..100} | filter foo bar r3 However, this adds a number of extra buffers and steps, so alternatively, you can make careful use of eval. This is OK ...


0

if [ -z "$(find . -name '*.part' -mmin -30)" ] then echo ".part file is old" else echo ".part file is recent" fir


1

Use $(...) instead of `...` -- see https://mywiki.wooledge.org/BashFAQ/082 bash can do arithmetic, you don't need to call out to expr. Don't parse ls curr_epch_buff=$( date -d '30 minutes ago' +%s ) for file in *.part; do file_mtime=$( stat -c '%Y' "$file" ) if (( file_mtime < curr_epch_buff )); then echo "$file is older than 30 minutes" ...


0

Each open file gets assigned a file descriptor and the file descriptor for stdin is 0 stdout is 1 stderr is 2 For opening additional files, there remain descriptors 3 to 9. Take for example exec 3>&1 4>&2 exec 1> /proc/1/fd/1 2>&1 3>&1 creates a new file descriptor and redirect it to 1 which is STDOUT 4>&2 also new ...


0

You can capture any valid MAC (with a leading space) with this regex: command | grep -oE '([ :][[:xdigit:]]{2}){6}' Or, in bash shell: $ regex='(([[:xdigit:]]{2}:){5}([[:xdigit:]]{2}))'; $ [[ $var =~ $regex ]] && printf '%s\n' "${BASH_REMATCH[1]}" aa:bb:cc:dd:ee:ff


1

You can use grep for this: $ cat good home/svdev/src/lib home/dev/project/doc home/server/etc dev.dump/trunk/src dev.dump/src/etc $ $ cat bad home/svdev/src/lib home/dev/project/doc home/server/etc dev.dump/trunk/src dev.dump/src/etc etc/hosts template.txt admin/releases/tables $ $ if grep -q -v -E '^home/|^dev\.dump/|^[[:space:]]*$' good; then echo ...


0

You can try using grep(1) and an if-statement if grep -Evq '^(home|dev\.dump).*' file.txt ; then echo false; fi


1

I wanted a more strict solution. I don't want to grep for Number of created files: (the message could be in another language) or remove all lines but two in -v output (who knows what summary rsync will print in the next version?). I found that you can set the format of a rsync's log, but not the format of its stdout (see man rsyncd.conf). For example, add ...


0

Use sem from GNU Parallel: sem --id givenum give-next-number-program


1

With GNU Parallel you should be able to do this: parallel --tty -j0 ::: 'openocd -f connect_swo.cfg' 'python3 swo_parser.py' If GNU Parallel is not already installed look at: https://oletange.wordpress.com/2018/03/28/excuses-for-not-installing-gnu-parallel/


0

This isnt a task thats appropriate for shell scripting. Do yourself a favor, and use a programming language for this task. For example with PHP: <?php $services = ['dataservive' => 'latest']; $serviceTag['source'] = 'ccr'; $serviceTag['services'] = $services; # example 1 print_r($serviceTag); # exmaple 2 echo json_encode($serviceTag), "\n"; Result: ...


1

I do not know ngram-merge so I use cat: n=$(ls | wc -l) while [ $n -gt 1 ]; do parallel -N2 '[ -z "{2}" ] || (cat {1} {2} > '$n'.{#} && rm -r {} )' ::: *; n=$(ls | wc -l); done But it probably looks like this: n=$(ls | wc -l) while [ $n -gt 1 ]; do parallel -N2 '[ -z "{2}" ] || ( /vol/customopt/lamachine.stable/bin/ngram-merge -write '$n'....


1

According to the GNU project's Bash reference manual, Bash's arrays are one-dimensional, whether they be indexed or associative. That means you can't nest them. Sorry to be the bearer of bad news, but I don't think what you're trying to do is possible.


1

You can try awk my_command_with_output | awk -F'[()]' '/^WIFI_MAC_Address/{sub(/^.*: /,"");print $1}' You can put it in a varialbe variable=$(my_command_with_output | awk -F'[()]' '/^WIFI_MAC_Address/{sub(/^.*: /,"");print $1}') Print out the content of the variable. echo "$variable" Output aa:bb:cc:dd:ee:ff


1

If I understand you correctly: echo "$var" | grep -o "..:..:..:..:.." Output: aa:bb:cc:dd:ee:ff


3

If you’re using GNU ls, you can use its --time-style option: ls -l --time-style=+%s


0

I do it another way around. I often want to use the variable name for e-mails, logs or flags (written to the disk) so that everything belonging to one device is named the same way - using the variable name as the base. RPiZero=10 ReadRPiTemp () { eval ReadSegment='$'$1 echo "variable content: $ReadSegment" echo "variable name: $1" } ...


0

The idea how to solve this problem is cd to the base directory home/Desktop/Work loop over all directories ????_? (loop variable dir) if there is a matching file $dir.pdb cd into the directory $dir loop over all Pocket_*_$dir.pdb run the command to process the data and to create the corresponding output file if successful extract the data from the ...


1

You can do this with GNU tools (it's not POSIX) and bash or some other array-capable shell #!/bin/bash # An associative array declare -A names # Iterate across the files, stripping version numbers and saving the name/prefix for file in *.rpm do name=${file%%-[1-9]*} # Assume "-" and a non-zero digit marks the version ((names[$name]++)) done ...


0

Not sure but you can try. printf '{"%s":"%s","%s":"%s":{"%s":"%s"}}\n' "${!serviceTag[@]}" "${serviceTag[@]}" "${!services[@]}" "${services[@]}"


0

I would make a python script in your case ,something like this a.py: import os import re highestFile='a' files = [f for f in sorted(os.listdir('.')) if os.path.isfile(f)] for f in files: if highestFile[0]==f[0]: if highestFile<f: highestFile=f else : print(highestFile) highestFile=f For example this would ...


1

1. @Kusalananda's filter won't be able to filter an array in place; if the same array is given as both the source and the destination, it will just truncate it. That could be easily fixed by rewriting the function as this: filter() { local cb=$1 i j a; local -n src=$2 dst=$3 for a in "${src[@]}"; do "$cb" "$a" && dst[...


1

Use the -R option of less, so that it interprets these codes as colour. It is rendering the codes in a human readable way. However can pass them to the terminal to be interpreted as colour. -r passes everything to terminal, -R only does this for colour. curl cheat.sh/python | less -R


0

You can use below one line awk command to kill the process Tested and worked fine ps -eaf | awk '/AmbariAgent.py/ && $0 !~ /awk/{print "kill -9" " " $2}'|sh


0

I came across a good example of 'space' and thought of sharing here. The following condition doesn't evaluate to true for i being somewhere between 100 and 1000. if [ $i -ge 100 -a $i -lt 1000]; then <some code here> fi Notice a missing space between 1000 and closing square bracket But when it is changed to as mentioned below, it works as expected....


2

If you are trying to kill the AmbariAgent process, then you can use a far shorter and more efficient command to kill it based on the name: pkill -f AmbariAgent Or whatever the name actually is: pkill -f <name> Added the -f switch so that it's matched against the entire line and not just the process name.


0

If I understand your spec - which is not too clear not consistent - correctly, you need two loops to a) find the primary .pdb files, and b) the related pocket files. After having created (and overwritten older versions of) the output.txt file, use awk to extract the desired fields into the result file. After having cd ed int the ALL dir, try for FN1 in *...


5

You give your function input on a single line. The line will be the string 1 2 3 4 which is what "${integers[*]}" expands to with the default value of $IFS. This entire single line will be read by the first call to read into arg and used (unquoted) in a call to your function. Since $arg is unquoted, the shell will spit the string on the spaces and your ...


4

The keyword for this is source (or simply .) instead of include. Add this to your .bashrc: # Include more scripts source /path/to/ide.bashrc source /path/to/git.bashrc or # Include more scripts . /path/to/ide.bashrc . /path/to/git.bashrc or include all from one directory: if [ -d /path/to/includes ]; then for f in /path/to/includes/*.bashrc; do ...


3

As the other answer is not POSIX, here is an alternative. If you want to crush the position arguments temporarily, you can do something like this: s1=$(printf '%s\n' "$@") then when you are ready to restore, do this: IFS=' ' set -- $s1 Note this assumes the arguments do not contain newlines. If they do, a different delimiter will need to be used. Side ...


0

Short bash script that uses GNU datamash to find the maximums: #!/bin/bash mapfile -t files < <(datamash -st'-' -g1 max 2 < "$1") IFS=, echo "${files[*]}" Usage: $ ./example.sh input.txt ac-2,bc-2


0

On older version of Modules (<4) code generated through the puts command is outputted first. On newer version of Modules (4+) it is outputted after all environment change. Anyway, you can simplify your setup whatever the Modules version used as you can rely in the modulefile on the GMXBIN environment variable defined with the setenv command. You can ...


1

Here is a echo-version (instead of rm, easier to test) of what I think makes sense. The idea is to split it up in two parts. First, test for empty and remove conditionally. Then, rm with option -f the 4 variations. Here it is 4 echoes on two lines, nicely formatted to show the whitespace in the filename. f="$1" [ -e "$f" ] && [ ! -s "$f" ] &&...


2

This lists file recursively in directory «directory-name», that are regular files, have a name starting with a dot (hidden), and are empty find «directory-name» -type f -name ".*" -empty


7

$@ is an array, assign it to an array: args=("$@") Then use it as an array: elif [[ $commit == true ]]; then git commit "${args[@]}" elif [[ $checkout == true ]]; then git checkout "${args[@]}" else What's happening in your current code is that all of your separate arguments are being stored as a single string. So if you call: bc -a "foo bar" ...


0

You can sort the filenames in reverse and then select the first occurrence of each filename: $ cat input ac-1 ac-2 bc-1 bc-2 $ cat input | sort -r | awk -F '-' '!seen[$1]++' bc-2 ac-2 The awk command takes '-' as delimiter and then prints each line where an ...


1

Use the right syntax for the calculation: x=$((x*5))


Top 50 recent answers are included