Tag Info

Hot answers tagged

11

Generally, you only have to escape one time to make special character considered literal. Sometime you have to do it twice, because your pattern is used by more than one program. Let disscuss your example: man gcc | grep \\. This command is interpreted by two programs, bash interpreter and grep. The first escape causes bash knows \ is literal, so the ...


7

Your grep prints all lines containing non-punctuation characters. That's not the same as printing all lines that do not contain punctuation characters. For the latter, you want the -v switch (print lines that don't match the pattern): grep -v '[[:punct:]]' file.txt If, for some reason you don't want to use the -v switch, you must make sure that the whole ...


7

Using gawk and assuming that the year always ends the record: awk -F"[0-9]{4}$" '{print $1}' movies


6

bash: while read -r line; do if [[ $line =~ (.*)[[:blank:]]+[0-9]{4}$ ]]; then echo "${BASH_REMATCH[1]}" fi done < data sed: sed 's/[[:blank:]]\+[0-9]\{4\}$//' < data


6

The standard test command also known as [ doesn't have a =~ operator. Most shells have that command built-in nowadays. The Korn shell introduced a [[...]] construct (not a [[ command) with alternate syntax and different parsing rules. zsh and bash copied that to some extent with restrictions and many differences but that never was standardized, so ...


6

With the Perl rename tool (which is called rename on Debian and friends including Ubuntu, it may be prename elsewhere): rename -n 's/(?<!\.)jpg$/.jpg/' * # -n makes it show you what it'll do, # but not actually do it. Remove the -n to # actually rename To break down that patter: the ...


5

By default sed uses POSIX Basic Regular Expressions, which don't include the | alternation operator. Many versions of sed, including GNU and FreeBSD, support switching into Extended Regular Expressions, which do include | alternation. How you do that varies: GNU sed uses -r, while FreeBSD, NetBSD, OpenBSD, and OS X sed use -E. Other versions mostly don't ...


5

In bash old test [ does not support regex. You must use new test [[ instead: re="\/$" if [[ $1 =~ $re ]]; then echo "${ATTENTION_PREFIX}$1 DIRECTORY MAY NOT CONTAIN A \"/\" OR LITERAL SLASH!${ATTENTION_POSTFIX}" exit 1 fi You can see more here. You'll need to change your #!/bin/sh shebang line to #!/bin/bash, as well.


5

Change #!/bin/sh to #!/bin/bash, and use double brackets instead: if [[ $1 =~ $re ]]; then This is the extended test command, as opposed to the (regular) test command. =~ can only be used with the [[ ... ]] version, and requires Bash 3.0 or later.


5

This is really quite simple. As long as the last field, the year, does not contain any whitespace (this is not clear from your question but I am assuming it is the case), all you need to do is remove the last field. For example: $ cat movies Casablanca 1942 Eternal Sunshine of the Spotless Mind 2004 He Died with a Felafel in His Hand ...


4

If you're using GNU sed (which bare -i suggests you are), there is a "word boundary" escape \b: sed -i "s/\b$SEARCH\b/$REPLACE/g" \b matches exactly on a word boundary: the character to one side is a "word" character, and the character to the other is not. It is a zero-width match, so you don't need to use capturing subgroups to keep the value with \1 and ...


4

The best strategy would be to use a proper html parser that can spit out the value of all <a> tags. Here, xmlstarlet is specifically an XML parser, and your HTML may not be well-formed XML, but you might get the idea: echo '<html> <a href="000000.jpg" title="image name.jpg" target="_blank">Image name.jpg</a> </html>' | ...


4

A GNU awk solution that treats , or \n as a record separator and - as a field separator. An equality check or a range check is applied depending on number of fields awk -v num=348 -v RS=',|\n' -F'-' 'NF == 2 && $1 <= num && $2 >= num{c++}; NF == 1 && $0 == num{c++}; END{print c+0}' file 2


3

Can you do this only using POSIX sed? Yes: sed -e 's/.^H//g' < data where ^H is just a literal backspace character. POSIX sed uses POSIX basic regular expressions, which are defined over bytes - printing characters or not, they don't care, so this behaves the same as if ^H were a letter. There are no extensions involved here. Note that all you really ...


3

This happends because (a|b) is a regular expression use -r option to deal with this: echo 'cat dog pear banana cat dog'|sed -r 's/cat|dog/Bear/g' from sed manpage: -r, --regexp-extended use extended regular expressions in the script.


3

The syntax \t for a tab character in sed is not standard. That escape is a GNU sed extension. You find a lot of examples online that use it because a lot of people use GNU sed (it's the sed implementation on non-embedded Linux). But OS X sed, like other *BSD sed, doesn't support \t for tab and instead treats \t as meaning backslash followed by t. There are ...


3

You could also use perl, which should support \b on all platforms. Assuming your list of replacements is in the format you show (separated by ->), you could do: perl -F"->" -ane 'chomp;$rep{$F[0]}=${$F[1]}; END{open(A,"file"); while(<A>){ s/\b$_\b/$rep{$_}/g for keys(%rep); ...


3

If you want more portable, you can use \< and \>: sed -i "s/\<$SEARCH\>/$REPLACE/g" file \< and \> work in gsed, ssed, sed15, sed16, sedmod. \b and \B work in gsed only. In Mac OSX, you must use this syntax: sed -i '' -e "/[[:<:]]$SEARCH[[:>:]]/$REPLACE/g" file


3

You could do something like: $ echo 'aabiicaa' | perl -lne ' while (/aa|ii/g) {print substr($`,-3)."[$&]".substr($'\'',0,2)}' [aa]bi aab[ii]ca iic[aa]


3

I assume the movie data will look something like below. cat movies one flew over the cuckoo's nest 1975 taxi driver 1976 the shining 1980 Now, I also assume the years in the movie data will always be 4 characters at the end. So, now if you use the commands as below, awk '{ gsub (" ", "", $0); print}' movies | rev | cut -c 5- | rev ...


3

$ egrep -l "\b1-[[:digit:]]{3}-[[:digit:]]{3}-[[:digit:]]{4}\b" \ /etc/* 2>/dev/null | sort > ~/etcphone.txt The \b escape sequence matches a word boundary. This will prevent if from matching something like 1231-123-123-1234.


3

* means 0 or more, so effecively 0 or more s characters. There's the documentation here, that says For example, ph*' applies the*' symbol to the preceding h' and looks for matches of onep' followed by any number of h's. This also matches justp' if no `h's are present. In your case, you're doing opens* while you're probably expecting something like ...


3

If you can use perl: $ perl -F',' -anle ' for (@F) { ($l,$h) = split "-"; $count++ if $l == 348 || ($l < 348 and $h >= 348); } END {print $count} ' file 2


3

While sed is a very useful and versatile tool, you're not using it properly. It's best used to match and substitute strings in text files; it can't directly rename files on the filesystem. This task is better suited for a bash one-liner (assuming that's your shell). To rename something like . filejpg to file.jpg, use this: find . -name '. *' -print0 | ...


2

Your regular expression is target="_blank">([[:graph:]]*)\.(jpg|png|gif|webm) This matches the literal text target="_blank">, followed by any number of non-whitespace characters, with one of the four strings .jpg, .png, .gif or .webm at the end. For example, the grep command would output the bold parts of the following lines: <a … ...


2

I don't have any problem with [[:space:]]. Here's a really silly little example showing the mixed-replacement of spaces and tabs: $ echo -e 'A \t \t B' | sed 's/A[[:space:]]*B/WORKED/' WORKED You can also use \s which is often preferable with big sed strings because it's much shorter: $ echo -e 'A \t \t B' | sed 's/A\s*B/WORKED/' WORKED Anyway, I ...


2

The portable way to do this - and the more efficient way - is with addresses. You can do this: printf %s\\n cat dog pear banana cat dog | sed '/cat/!{/dog/!b};cBear' In this way if the line does not contain the string cat and does not contain the string dog sed branches out of the script, autoprints its current line and pulls in the next to begin the next ...


2

This answer will provide the fields that contain the specified number, not just the lines, if you are after that level of detail (and if the ranges in your data might contain overlaps): awk -v num=348 -F, '{ for (i=1; i<=NF; i++) { if ($i == num || (split($i, a, /-/) == 2 && (a[1] <= num && num <= a[2]))) { print $i ...


1

Use a Bash specific quoting which lets you use strings like in C, so that a real tab character is passed to sed, not an escape sequence: sed -i.bak -E $'s/\t/ /' file.txt


1

This should remove the last numeric characters and the tabs and spaces before it: sed -e 's#[\t ]*[0-9]*$##' movies.txt



Only top voted, non community-wiki answers of a minimum length are eligible