Tag Info

New answers tagged

4

Could use awk for the whole thing. Awk is also far quicker than while read loops. awk -vM="$Message" '$1==M{print "Translated:",$2"-"$3}' CODE-LIST.txt Explanation -vM="$Message" - Create a variable named M with the value from $Message $1==M - If the first field is equal to variable M($Message) {print "Translated:",$2"-"$3} - ...


6

How about: while read code device state junk; do if [[ $code == $message ]]; then echo "Translated: $device-$state" fi done <CODE-LIST.txt Using extra processes (i.e. forking awk everytime) will slow it a lot. read will read multiple fields, separated by $IFS (default value is all white space). The last variable listed will receive the ...


3

test=$line i=0 while case "$test" in (*select*) test=${test#*select};;(*) ! :;; esac; do i=$(($i+1)); done You don't need to call grep for such a simple thing. Or as a function: occur() while case "$1" in (*"$2"*) set -- \ "${1#*"$2"}" "$2" "${3:-0}" "$((${4:-0}+1))";; (*) return "$((${4:-0}<${3:-1}))";;esac do : ...


11

Have grep read on its standard input. There you go, using a pipe... $ echo "$line" | grep select ... or a here string... $ grep select <<< "$line" Also, you might want to replace spaces by newlines before grepping : $ echo "$line" | tr ' ' '\n' | grep select ... or you could ask grep to print the match only: $ echo "$line" | grep -o select ...


1

You could use this expr length $str Hopefully this should help!


1

You can use sed to convert all / into \ by following command: sed 's/\//\\/g' Example: $ echo $PWD | sed 's/\//\\/g' \home\pandya Another way is to use tr: tr '/' '\\' By above command, tr convertes all / with\; Example: $ echo $PWD | tr '/' '\\' \home\pandya


3

I'm not entirely sure what you're trying to do but changing the slashes is easy: $ printf '%s\n' "${PWD//\//\\}" \home\terdon This is using ksh's string manipulation capabilities also available in bash. Specifically, ${foo//bar/baz/} will replace all occurrences of the string bar with baz in the variable $foo. Since / and \ are special characters, they ...


1

As a shell solution, getopts is probably easiest. The thing about getopts is that it is POSIX-specified to do exactly what you're asking - process a byte-stream in a shell-loop. I know that sounds weird, because, if you're like me before I learned this, you're probably thinking, well, gee, I thought it was supposed to handle command-line switches. Which is ...


3

Two lines Here is a pure-bash solution that produces a bash array: s="100000011100" array=($( for ((i=0; i<${#s}-6; i++)) do echo "${s:$i:1}${s:$((i+6)):1}" done )) echo "${array[@]}" This produces the same output as shown in the question: 10 01 01 01 00 00 The key element here is the use of bash's substring expansion. Bash ...


1

sed is the first thing that pops into my mind. $ echo 1234567890abcdefghijklmnopqrstuvwxyz | sed 's/.\{5\}\(.\)/\1/g' 6bhntz Match 5 characters, capture the 6th, and replace them all with that captured character. This will however have an issue if the length of the string isn't an exact multiple of 6: $ echo 1234567890abcdefghijklmnopqrstuvwxy | sed ...


3

Using perl: $ echo 100000011100 | perl -nle ' for ($i = 0; $i < length()/2; $i++) { print substr($_,$i,1), substr($_,$i+6,1); } ' 10 01 01 01 00 00 It works for two lines. If you want to work with arbitrary of lines, you should process lines directly, instead of building big string. With this input: 1 0 0 0 0 0 ...


0

You can call external utilities (see other answers), but they will make your script slower, and it's hard to get the plumbing right. In zsh, you can write ${#$(readlink -f /etc/fstab)} to get the length of the command substitution. Note that this isn't the length of the command output, it's the length of the output without any trailing newline. If you want ...


0

This works in dash but it does require that the targeted var is definitely empty or unset. That is why this is actually two commands - I explicitly empty $l in the first: l=;printf '%.slen is %d and result is %s\n' \ "${l:=$(readlink -f /etc/fstab)}" "${#l}" "$l" OUTPUT len is 10 and result is /etc/fstab That's all shell builtins - not including ...


4

I usually do it like this: $ echo -n "$variable" | wc -m 10 To do commands I'd adapt it like so: $ echo -n "$(readlink -f /etc/fstab)" | wc -m 10 This approach is similar to what you were doing in your 2 steps, except we're combining them into a single one liner.


5

Not sure how to do this with shell builtins (Gnouc is though) but the standard tools can help: You can use wc -m which counts characters. Unfortunately, it also counts the final newline so you'd have to get rid of that first: readlink -f /etc/fstab | tr -d '\n' | wc -m You can of course use awk readlink -f /etc/fstab | awk '{print length($0)}' Or Perl ...


5

With GNU expr: $ expr length "$(readlink -f /etc/fstab)" 10 With unicode string, expr does not seem to work, because it returns length of string in bytes instead of characters count (See line 654) $ LC_ALL=C.UTF-8 expr length ăaa 4 So, you can use: $ echo -n "ăaa" | LC_ALL=C.UTF-8 wc -m 3


3

As I understand it you're looking for the value of "Foo". This is really easy to do with the shell command-line tool jq. It is something like sed in that it implements its own kind of parser language. Given your example: json=' { "Reservations" : { "OwnerId" : "1345345", "Groups" : [], "SecurityGroups" : [ ...


2

This is an answer to your objective, but not your question. Meaning you can accomplish your goal without using a JSON parser. The AWS cli util has the ability to only output select fields using the --query argument. This is documented here. For example: $ aws ec2 describe-instances \ --query 'Reservations[0].Instances[0].SecurityGroups[0].GroupName' \ ...


0

sed -e 'h;s/.*intron_[^:]*\(:[^[:space:]]*\).*/\1/;s/./ /g;;G;;s/\(.*\)\n\(.*\)intron_\([^:]*\):[^[:space:]]*/\2\3\1/' YourFile In 1 sed (no pipe) keeping the column. It use the holding buffer Posix version (so --posixon GNU sed)


1

You can use perl: $ perl -anle ' BEGIN {$" = "\t"} print "@{[@F]}" and next if $. == 1; $F[1] = $1 if /_([^:]*):/; print "@{[@F]}"; ' file id target_id length eff_length 1 FBgn0000721 1136 243.944268 1 FBgn0000721 1122 240.237419 2 FBgn0264373 56 0 3 FBgn0027570 54 0 Explanation -a: auto split each line into ...


5

Using sed and column: $ sed -E 's/ intron_([^:]*):[^[:space:]]*/ \1/' file | column -t id target_id length eff_length 1 FBgn0000721 1136 243.944268 1 FBgn0000721 1122 240.237419 2 FBgn0264373 56 0 The key part of this is the substitute command: s/ intron_([^:]*):\S*/ \1/ It looks for intron_ and saves everything after intron_ ...


0

Another perl: $ w | head -1 | perl -nle 'print +(split /load average:/)[-1]' 0.42, 0.49, 0.63


5

You can also use awk: $ w | head -1 | awk '{print $10,$11,$12}' 0.80, 0.84, 0.93 Or, if the number of fields is variable, use: $ w | head -1 | awk '{print $(NF-2),$(NF-1),$NF}' 0.81, 0.82, 0.91 Or, the much more elegant (thanks @Letitzia): $ w | head -1 | awk -F "load average: " '{print $2}' Sed: $ w | head -1 | sed 's/.*load average: *//' Perl: ...


3

Normally I'd just use the ${parameter#word} bash parameter expansion. It expands $parameter, deleting word (which can be a pattern) from the start. In your case, something like: line=... echo ${line#*load average: } Making it a function: get_load() { w | head -n 1 | { read -r line; echo ${line#*load average: }; } }


3

If you want only last numbers you can use grep: $ w | grep -Po 'load average: \K.*' 0.07, 0.13, 0.09


8

because $test contains whitespace, when you say myfunc $test # without quotes your function receives > 1 argument. myfunc receives 2 arguments here, aaaaa and aaaaa. You want this: myfunc "$test" # with quotes Rule of thumb: always quote your "$variables" unless you know exactly when and why not to.


0

What you have is very close, simply replace grep -i with egrep, i.e. egrep ^[qwrtypsdfghjklzxcvbnm]*[aeodsui]+[qwrtypsdfghjklzxcvbnm]$ [filename] should do the trick.


0

As @l0b0 said, I don't think this can be done in a single step in the shell but it's simple enough to do with external tools (this assumes the string is saved in the variable $s): $ perl -pe 's#[.\-/]##g' <<<$s | grep -oP .{16} mysitesubdomainc


2

Why not use zsh? $ echo ${${mysite//[\.\/-]/}:0:16} mysitesubdomainc (I slightly modified you code)


3

There's no way to chain the Bash built-in parameter expansion, but of course this can be done in a single line with external tools like sed: $ sed 's/[\.\/-]//g;s/^\(.\{16\}\).*/\1/' <<< "./my-site.sub.domain.com" mysitesubdomainc Unfortunately this very quickly turns into unmaintainable code, and is probably less efficient than using Bash ...



Top 50 recent answers are included