New answers tagged

1

perl -00 -n -e 'print if (m/blue/i && m/green/i && m/yellow/i)' filename This uses perl's paragraph-reading mode (-00) to print only paragraphs containing all three words (with case-insensitive matches). a 'paragraph' is one or more lines of text, separated from other paragraphs by at least one blank line. e.g. I saved the text of your ...


0

Or with awk, using the regexp <|> as the field delimiter: $ echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | awk -F '<|>' '{print $3}' {41c33a-4893b-3627a-617a} Note: tested with GNU awk, mawk, and original-awk. Works the same in all three. The perl version is very similar (except perl arrays are ...


0

You can also have sed extract the field specified by a regular expression. Useful if you have more complex matching criteria: echo '<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>' | \ sed -E 's/^.+>({.+})<.+$/\1/'


1

For simple string manipulations, you should generally use the shell's own constructs, tied to parameter expansion. External utilities are better at processing large volumes of text, but for a single string, launching an external tool is slow and getting the quoting right can be difficult. ...


2

You can use cut's -d option to define a delimiter (which is excluded from the resulting fields): echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | cut -d\> -f2 | cut -d\< -f1 This splits on > and outputs the second field, leaving {41c33a-4893b-3627a-617a}</xml:attribute, then again on < and outputs the first ...


1

Here is a way that should work with all Bourne syntax / POSIX shells and uses only builtins : if (set -f ; IFS=$'\n'; set -- x${myvar}x ; [ $# = 1 ]) ; then echo "Your variable has only one line, proceeding" else echo "Error condition, variable must have exactly one line" fi If your shell doesn't support IFS=$'\n' (like dash 0.5.7), you can use ...


3

There are several options (bash first, POSIX is below). The code inside each function could be easily used outside. #!/bin/bash nl=$'\n' aregex (){ [[ $a =~ $nl ]]; } apattern (){ [[ $a == *$nl* ]]; } acut (){ [[ $a != "${a%%"$nl"*}" ]]; } areplace (){ [[ $a != "${a//"$nl"/}" ]]; } acase (){ case $a in (*$nl*) true;; (*) ...


5

The following snippets works in bash (with and without the -posix option): #!/bin/bash #!/bin/bash -posix version_1 () { [[ "$myvar" = *$'\n'* ]]; } version_2 () { local newlines="${myvar//[^$'\n']/}" [[ "${#newlines}" -eq 1 ]] } for test in version_1 version_2; do if $test; then echo many lines; else echo one line; fi done


7

The POSIX way: NL=' ' case $myvar in *"$NL"*) echo more than one line ;; *) echo one line ;; esac This also works in pre-POSIX Bourne-like shells, too.


-1

Pure bash, it's the same thing as Wildcard's 2nd method earlier, but this is on one line: echo -e "${PATH//:/"\n"}"


-1

This script works similar to the command where #!/bin/bash fn="foo" for i in `echo $PATH|tr ':' '\n'` do if [[ -e "$i/$fn" ]] ; then echo $i fi done $fn is something you want to find. $i/$fn may be $i$fn sometimes.


5

read uses IFS to separate the words in the line it reads, it doesn't tell read to read until the first occurrence of any of the characters in it. IFS=: read -r a b Would read one line, put the part before the first : in $a, and the rest in $b. IFS=: read -r a would put the whole line (the rest) in $a (except if that line contains only one : and it's ...


-1

Shell utils: echo $PATH | tr ':' '\n'


2

Don't use shell loops to process text. Instead, use awk, or tr, or even sed. printf %s\\n "$PATH" | tr ':' '\n' printf %s "$PATH" | awk 'BEGIN {RS=":"}; 1' Or, since this is a shell variable you are processing, just use bash pattern substitution: echo "${PATH//:/ }" (See LESS=+/parameter/pattern man bash.)


2

IFS=. read -r first second third fourth fifth <<< "$var" This sets the field separator to "." then tells bash to read into the named variables from the input provided by your $var's contents.


1

ZSH is delightfully free of the word-splitting behaviour seen in other shells (unless for some bizarre reason the SH_WORD_SPLIT option has been turned on), so there is no need to use strange double-quoting constructs. % (){ print -l $* } a b c a b c % (){ print -l "$*" } a b c a b c % (){ local msg; msg="$*"; print -l $msg } a b c a b c % Thus, the ...


2

The usual way is to do it in two steps: x=foobarbaz y=${x#foo} # barbaz z=${y%baz} # bar As this are "Parameter Expansions", a "Parameter" (variable) is needed to be able to perform any substitution. That means that y and z are needed. Even if they could be the same variable: x=foobarbaz x=${x#foo} # barbaz x=${x%baz} # bar ...


5

I don't think that's possible (but would love to be proved wrong). However, you can use an intermediate variable. The bash -c run by -exec is just a bash instance, like any other: $ find . -type f ./foobarbaz $ find . -type f -exec bash -c 'v=${0#./foo}; echo ${v%baz}' {} \; bar So I see no reason why this wouldn't work (if I understood what you're ...


1

I always do it one step at a time: X=foobarbaz; X="${X#foo}"; X="${X%baz}"



Top 50 recent answers are included