Tag Info

New answers tagged

1

You should just split it and choose the parts you want: ( IFS=/ ; set -- $string while ${1+:} false ; do echo "$1" ; shift done ) To get only the beginning/end: start_end="$(IFS=/ ; set -- $string ; unset IFS printf '/%s/.../%s' "$1" \ "`shift $(($#-1)) ; echo "$1"`" )"


2

This sed command runs a regex that should be helpful for your task: sed 's#\(/[^/]\+/[^/]\+/\).*\(/[^/]\+/[^/]\+\)/\?#\1...\2#g' Test: PS1PWD_REGEX='s#\(/[^/]\+/[^/]\+/\).*\(/[^/]\+/[^/]\+\)/\?#\1...\2#g' $ echo "~/apps/webs/2014/" | sed $PS1PWD_REGEX ~/apps/webs/2014/ $ echo "~/apps/webs/chip/mips/2014/" | sed $PS1PWD_REGEX ~/apps/webs/.../mips/2014 ...


5

Ok, so I guess your problem was that multiple-quote marks per line were pulling in more than you wanted because regex is inherently greedy - it will always match as much as possible if it can. So the solution is to ensure you only match between the two double-quote marks, like: grep -o 'CLASS_NAME:"[^"]*"' script.js


2

GNUly: s1='token1, token2, token3, token4, token5, token6, token8, token9, token10' s2='token2, token7, token4, token3, token5, token6, token8, token10, token9' comm <(grep -oE '\w+' <<< "$s1" | sort) <(grep -oE '\w+' <<< "$s2" | sort) Gives: token1 token10 token2 token3 ...


1

Pinching the basic idea from Ramesh With GNU awk in bash awk -v RS='[[:space:]]*,[[:space:]]*' '{x[$0]++}; END{for (y in x) if (x[y] == 1) print y}' <(printf "%s" 'token1, token2, token3, token4, token5, token6, token8, token9, token10') <(printf "%s" 'token2, token7, token4, token3, token5, token6, token8, token10, token9') token1 token7


1

You can do something like below. cat input1 input2 >> output arr=$(cat output | tr "," "\n") echo "${arr[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ' Explanation I am merging the 2 files together into another file and splitting the tokens with comma as a delimiter. After that I am printing only the values that are unique (meaning only the values ...


1

SOLUTION: ( set -- *files ; for f ; do ( set -- $(printf %c\ `cat <$f`) while [ $# -ge 1 ] ;do [ -z "${1#"$2"}" ] && { echo "$f"; break ; } || shift done ) ; done ) DEMO: First, we'll create a test base: abc="a b c d e f g h i j k l m n o p q r s t u v w x y z" for l in $abc ; do { i=$((i+1)) h= c= ; [ $((i%3)) -eq 0 ] && ...


0

This script uses grep and cut to obtain line numbers of matching lines, and checks for any two consecutive numbers. The file is assumed a valid filename passed as the first argument to the script: #!/bin/bash checkfile () { echo checking $1 grep -n -E "^C.*$" $1 | cut -d: -f1 | while read linenum do : $[ ++PRV ] if [ $linenum == ...


2

Yet another option with GNU sed: For a single file: sed -n -- '/^C/{n;/^C/q 1}' "$file" || printf '%s\n' "$file" (though it will also report the files it cannot read). For find: find . -type f ! -exec sed -n '/^C/{n;/^C/q 1}' {} \; -print The problem with unreadable files being printed can be avoided by writing it: find . -type f -size +2c -exec sed ...


1

Assuming your files are small enough to be read into memory: perl -000ne 'print "$ARGV\n" if /^C[^\n]*\nC/sm' * Explanation: -000 : set \n\n as the record separator, this turns on paragraph mode which will treat paragraphs (separated by consecutive newlines) as single lines. -ne : apply the script given as an argument to -e to each line of the input ...


4

With pcregrep: pcregrep -rMl '^C.*\nC' . POSIXly: find . -type f -exec awk ' FNR==1 {last=0; printed=0; next} printed {next} /^C/ {if (last) {print FILENAME; printed=1; nextfile} else last=1; next} {last=0}' {} + (though that means reading all the files fully with those awk implementations that don't support nextfile). With versions of GNU ...


2

With awk: awk '{if (p ~ /^C/ && $1 ~ /^C/) print; p=$1}' afile.txt This will print contents of the file if there are consecutive lines starting with a C. The expression (p ~ /^C/ && $1 ~ /^C/) will look into successive lines in the file and will evaluate to true if the first character in both match C. If that is the case, the line will be ...


3

POSIXly: sed ':1 s/^\(.*|\)\{0,1\}\([0-9.]*[0-9][0-9.]*\)-\(|.*\)\{0,1\}$/\1-\2\3/ t1' Or with awk in a more intuitive way: awk -F '|' -v 'OFS=|' '{ for (i = 1; i <= NF; i++) if ($i ~ /^[0-9]*(\.[0-9]+)?-$/) $i = "-" substr($i, 1, length($i)-1) print}' (that version is stricter in what it considers to be a number, the sed ...


2

You can do it by anchoring the match to the beginning of the line or a separator. For example with a GNU sed extended regular expression: sed -r ':a; s/(^|\|)([0-9.]+)-(\||$)/\1-\2\3/; ta' infile Output: -123|aaa|bbb|123|123.0|-123|-123.01|-123.02|-123.03|aaa|bbb|-123|aaa-|-bbb|cc-cc|-123.04|aa123-|-123.05


1

rev is the obvious and probably the best answer. But rev is not always installed by default. If you want to do this purely with coreutils you can use this longer command: echo 123 | fold -w1 | tac | paste -d '' -s - fold -w1 puts each digit on a line tac is a reverse cat, i.e. reverses the order of the lines paste -d '' -s - serially pastes the digit ...


3

For those not limited to bash, with zsh: forward=123 backward=${(j::)${(Oas::)forward}} Those are variable expansion flags: s::: split on the empty string, so one element per character Oa: reverse the resulting array (O for reverse order, a for array subscript order). j::: join the elements with the empty string.


1

#!/bin/bash #set -xv string="$1" reverse_string="" string_length="${#string}" while (( "$string_length">=1 )) do string_length=$(( $string_length - 1 )) reverse_string="$reverse_string${string:$string_length:1}" done echo "$reverse_string" make the file executable $ chmod +x reverse_string $ ./reverse_string 123456789 98765432


2

Are you looking for rev? echo 123|rev 321


8

:~> echo 123456 | rev 654321 It should work. The usage is pretty simple. from man: NAME rev - reverse lines of a file or files SYNOPSIS rev [file ...] DESCRIPTION The rev utility copies the specified files to the standard output, reversing the order of characters in every line. If no files are specified, the ...


1

Process the arguments using bash, not external processes for ARG in "${PARGS_ARR[@]}" do # trim single quotes ARG=${ARG//\'} # split by equals sign IFS="=" read ARGL ARGR <<< "$ARG" if [[ "$ARGL" == "-DnodeId" ]]; then NODE=$ARGR fi done


1

It seems that what you're doing would definitely be very slow as every time you var=$(command substitute) you must stop and wait for its output before you move to the next step. I'm willing to bet you'd wait a lot less if you just processed it in stream with sed, the stream editor: NODE="$(pargs -l $PID | sed -rn '/(-DnodeId)=(\S*)/{s//\2/pq}')" I'm not ...


1

If all you care about is what comes to the right of = if what's on the left is -DnodeId, you can do this: NODE=$(pargs -l $PID| awk -F '-DnodeId=' '{sub(" .*","",$2);print $2}') This will print whatever comes to the right of the pattern -DnodeId= up to but excluding the first space. If there's more than one -DnodeId on the command line, it will work with ...


1

What does the output of pargs -l $PID look like? From your code, it seems like it is a single line containing all the command-line arguments in a format eg: arg1=val1 arg2=val2 If so, you can collect the value for the -DnodeId argument with a sed command: $ ARGS="-DfirstArg=foo -DanotherArg=bar -DnodeId=1234 -DlastArg=baz" $ echo "$ARGS" | sed -r ...



Top 50 recent answers are included