Tag Info

New answers tagged

0

In POSIX system, you can use expr: $ a=a $ expr "$a" - 0 >/dev/null 2>&1 $ [ "$?" -lt 2 ] && echo Integer || echo Not Integer


1

To remove a trailing slash if there is one, you can use the suffix removal parameter expansion construct present in all POSIX-style shells: x=${x%/} There are a few complications. This only removes a single slash, so if you started with a/b/c// then you'll still end up with a slash. Furthermore, if the original path was /, you need to keep the slash. ...


0

You can use the -eq test on the string, with itself: $ dash -c 'a="a"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi' dash: 1: [: Illegal number: a not a number $ dash -c 'a="0xa"; if [ "$a" -eq "$a" ] ; then echo number; else echo not a number; fi' dash: 1: [: Illegal number: 0xa not a number $ dash -c 'a="-1"; if [ "$a" -eq "$a" ] ; ...


5

Whether dash, bash, ksh, zsh, POSIX sh, or posh ("a reimplementation of the Bourne shell" sh) ; the case construct is the most widely available and reliable: case $1 in (*[!0-9]*|"") false ;; (*) true ;; esac


0

Perhaps with expr? if expr match "$1" '^\([0-9]\+\)$' > /dev/null; then echo "integer" else echo "non-integer" fi


0

Try using it as an arithmetic expansion, and see if it works. Actually, you need to be a bit stricter than that, because arithmetic expansions would ignore leading and trailing spaces, for instance. So do an arithmetic expansion, and make sure that the expanded result matches the original variable exactly. check_if_number() { if [ "$1" = "$((${1}))" ] ...


8

The following detect integers, positive or negative, and work under dash and are POSIX: Option 1 echo "$1" | grep -Eq '^[+-]?[0-9]+$' && echo "It's an integer" Option 2 case "${1#[+-]}" in ''|*[!0-9]*) echo "Not an integer" ;; *) echo "Integer" ;; esac Or, with a little use of the : (nop) command: ! case ${1#[+-]} in ...


4

dir=${1%/} will take the script's first parameter and remove a trailing slash if there is one.


3

Use the shell's string manipulation features that come with parameter expansion. These features are present in all non-antique Bourne-style shells including dash, bash and ksh. suffix=${OUTPUT#*SauceOnDemandSessionID=} SAUCE_ID=${suffix%%[!0-9A-Fa-f]*}


0

Using grep with PCRE, you can use the regex: SauceOnDemandSessionID=\K[^ ]*(?= job-name) Test: $ SAUCE_ID=$(grep -Po "SauceOnDemandSessionID=\K[^ ]*(?= job-name)" <<< "$OUTPUT") $ echo "$SAUCE_ID" 5c72e54365e9bb559ea389dc164ba754 It will be work in all cases given you have SauceOnDemandSessionID= before and job-name after the pattern.


3

This is how I would read a line at a time from a file while IFS= read -r DEVICE do .... done < your_file


0

If the ID is always the same length, and composed of only the letters a through f and numbers, and there are no similar strings in the output, you could do this: SAUCE_ID="$(echo $OUTPUT | egrep -o '[0-9a-f]{32}')" It searches for a string of 32 characters that are either a number in 0-9 or a letter in a-f. To allow variation in the length of the string, ...


1

Just for fun (and other shells) other variant: word=hello unset letter while [ ${#word} -gt 0 ] do rest=${word#?} letter[${#letter[*]}]=${word%$rest} word=$rest done And check for l in "${!letter[@]}" do echo "letter [$l] = ${letter[l]}" done will print letter [0] = h letter [1] = e letter [2] = l letter [3] = l letter [4] = o


0

Method 1: Oneliner: s="hello" for ((i=0;i<${#s};i++)); do result[$i]="${s:i:1}"; done echo ${result[@]} Expanded code: s="hello" # Original string. for ((i=0;i<${#s};i++)); do # For i=0; i<(length of s); i++ result[$i]="${s:i:1}" # result[i] is equal to the i th character of $s done # End of ...


2

To split string into array of characters, with null delimiter, you can: str='hello' arr=() i=0 while [ "$i" -lt "${#str}" ]; do arr+=(${str:$i:1}) i=$((i+1)) done printf '%s\n' "${arr[@]}" With delimiter other than null, you can: str='1,2,3,4,5' IFS=',' read -r -a arr <<<"$str" printf '%s\n' "${arr[@]}" or: set -f str='1,2,3,4,5' IFS=',' ...


4

s="hello" declare -a a for ((i=0; i<${#s}; i++)); do a[$i]="${s:$i:1}"; done declare -p a Output: declare -a a='([0]="h" [1]="e" [2]="l" [3]="l" [4]="o")' or s="hello" while read -n 1 c; do a+=($c); done <<< "$s" declare -p a Output: declare -a a='([0]="h" [1]="e" [2]="l" [3]="l" [4]="o")'


2

Using awk: awk '{print "level="$5"\n""grid="$12"\n""boxes="$15"\n""tasks="$18}' file level=512^3 grid=16^3 boxes=32^3 tasks=800


1

If the line always has exactly this structure, read can do this in a single line with no external processes: read x x x x level x x x x x x grid x x boxes x x tasks x <<<"$line" (also using a herestring). This will save all the words you don't care about into x (to be ignored) and the values you wanted into their respective variables.


9

Bash can match regular expressions with the =~ operator in [[ ... ]]: #! /bin/bash line='attempting to create a 512^3 level (with Dirichlet BC) using a 16^3 grid of 32^3 boxes and 800 tasks...' num='([0-9^]+)' nonum='[^0-9^]+' if [[ $line =~ $num$nonum$num$nonum$num$nonum$num ]] ; then level=${BASH_REMATCH[1]} grid=${BASH_REMATCH[2]} ...


2

If this is output from a program / script you've written and the text is formulaic (i.e. follows this pattern exactly) you can just use cut. #!/bin/bash $STRING='attempting to create a 512^3 level (with Dirichlet BC) using a 16^3 grid of 32^3 boxes and 800 tasks...' level=$(echo $STRING | cut -d' ' -f5 -) grid=$(echo $STRING | cut -d' ' -f12 -) ...


0

Using sed Here is a sed solution: $ sed '\|// copyright|,\|^package|{s/^package/Something\nElse/p;d}' file Something Else com.base import com.base import com.base ... Did you want to remove all of the original package line? If so, just a minor change is needed: $ sed '\|// copyright|,\|^package|{s/^package.*/Something\nElse/p;d}' file Something Else ...


2

If you don't mind using two different commands for the file names and content, the below commands will help you. find /sys -name "*filesystem*" The above command will find all the files/directories with "filesystem" as part of the filename/directoryname. grep -rn "filesystem" /sys/* The above command will look for all the files containing "filesystem" ...


1

To insert 1 in front of QQQQQ you can use sed 's/QQQQQ/1&/'. To replace the QQQQQ with 1 you can use sed 's/QQQQQ/1/'. I don't understand your concern about avoiding "simple substitution". If my suggestions are not suitable please update your Question with examples of "before" and "after" a typical substitution.


1

When you expand a variable outside of double quotes, as in expr $str2, the following things happen: Take the value of the variable. The result is a string. Split the value into whitespace-delimited chunks.¹ The result is a list of strings. Interpret each element of the list as a wildcard pattern, i.e. globbing. If it matches files, replace the element by ...


2

The following will produce wrong results: str2="( 1 + 2 + 3 + 4 + 5 ) / 3 + 5 * 2" expr $str2 The problem is that the shell considers * to be a wildcard file glob and will replace it with a list of files in the current directory. This is not what you want. expr is archaic. A more modern solution would use the shell's $((...)) form for arithmetic: $ ...


1

As you prefer a one liner, vector=("${vector[@]//\"/}") Remember that text substitutions could work for the array as a whole.


1

You'll make your program simpler and more robust if readdata.sh produces newline-delimited data, with no extra quotes. In your current program, the output of readdata.sh is split at whitespace (so e.g. "a b" results in two array elements "a and b") and each resulting word is interpreted as a wildcard pattern (so e.g. "a * b" results in "a, then the file ...


0

Since the question is How can I split the current working directory into an array? (and not “How do I get IFS="something" read -a arrayname <<< $(command) to work?”), I give you saveIFS="$IFS"; IFS=/ PARTS=($(pwd)); IFS="$saveIFS" Yeah, I know; it’s ugly.  I tried IFS=/ PARTS=($(pwd)) And it left IFS set to /, even if I enclosed it in { ...


2

It works if you quote the command. IFS="/" read -ra PARTS <<< "$(pwd)" for i in "${PARTS[@]}" do printf '%s\n' "$i" done home user1


4

This might work: in_file=./data vector=($(./readdata.sh 0 $in_file)) for index in ${!vector[@]} do echo ${vector[index]//\"/} done Ref: http://www.tldp.org/LDP/abs/html/refcards.html#AEN22828


1

With your regular expression you are recognizing: "RvA_X-IRB-il-CA101-RvA_X-IRB+020000-20150327212332-055582-P" in part because you are using \1 as others have pointed out. Note the repeated "RvA_X-IRB". However, it could be important to note that you are using "\b" as well, and this is going to work only when you do have a "non-word" character in one ...


1

echo "foo-bar-123"| awk -F"-" '{print $3}'


2

grep -Po '(?<=\w-)\w+(?=$|[\s.,])'


7

You can use Bash's parameter expansion: string="foo-bar-123" && printf "%s\n" "${string##*-}" 123 If you want to use another process, with Awk: echo "foo-bar-123" | awk -F- '{print $NF}' Or, if you prefer Sed: echo "foo-bar-123" | sed 's/.*-//' A lighter external process, as Glenn Jackman suggests is cut: cut -d- -f3 <<< "$string" ...


3

In any POSIX-compatible shell you can do: case $line in (*"$PWD"*) # whatever your then block had ;;esac This works in bash, dash, and just about any other shell you can name. It can also be used to handle multiple possibilities easily. For example: case $line in (*"$PWD"*) echo \$PWD match\! ;; (*"$OLDPWD"*) echo \$OLDPWD match\! ;; (*) ...


-1

The following will work bash, zsh, ksh and dash. line="I'm in a pickle, where is $HOME" whereami=$(echo $line | awk -v pwd=$PWD '$0 ~ pwd') if [ -z "$whereami" ];then echo "I'm on the wrong path" else echo "I'm on the right path" fi


2

Yes, recent versions of bash can do this: $ pwd /home/terdon $ line="I'm in /home/terdon" $ [[ "$line" =~ "$PWD"$ ]] && echo yes yes The same syntax works in zsh and ksh but not in dash. As far as I know, dash has no such capabilities. Note that your regex is checking whether the variable $line ends with $PWD. To check if $PWD matches anywhere in ...



Top 50 recent answers are included