Sed Directory Not Found When Running R with -E Flag

Unable to filter rows which contain Is a directory by SED/AWK

I have not used the md5deep tool, but I believe those lines are error messages; they would be going to standard error instead of standard out, and so they are going directly to your terminal instead of through the pipe. Thus, they won't be filtered by your sed command. You could filter them by merging your standard error and standard output streams, but

It looks like (I'm not sure because you are missing the backquotes) you are trying to call

md5deep `find *`

and find is returning all of the files and directories.

Some notes on what you might want to do:

  • It looks like md5deep has a -r for "recursive" option. So, you may want to try:

    md5deep -r *

    instead of the find command.

  • If you do wish to use a find command, you can limit it to only files using -type f, instead of files and directories. Also, you don't need to pass * into a find command (which may confuse find if there are files that have names that looks like the options that find understands); passing in . will search recursively through the current directory.

    find . -type f
  • In sed if you wish to use slashes in your pattern, it can be a pain to quote them correctly with \. You can instead choose a different character to delimit your regular expression; sed will use the first character after the s command as a delimiter. Your pattern is also lacking a .; in regular expressions, to indicate one instance of any character you use ., and to indicate "zero or more of the preceding expression" you use *, so .* indicates "zero or more of any character" (this is different from glob patterns, in which * alone means "zero or more of any character").

    sed "s|/.*||g"
  • If you really do want to be including your standard error stream in your standard output, so it will pass through the pipe, then you can run:

    md5deep `find *` 2>&1 | awk ... 
  • If you just want to ignore stderr, you can redirect that to /dev/null, which is a special file that just discards anything that goes into it:

    md5deep `find *` 2>/dev/null | awk ...

In summary, I think the command below will help you with your immediate problem, and the other suggestions listed above may help you if I did not undersand what you were looking for:

md5deep -r * | awk '{ print $1 }'

Sed command - order of option flags matters? (-ir vs -ri)

When doing -ir you are specifying that "r" should be the suffix for the backup file.

You should be able to do -i -r if you need them in that order

find + sed, filename output

If your file names don't contain spaces then all you need is:

awk '/pattern/{print FILENAME; cnt++; nextfile} END{print cnt+0}' $(find D:/Temp -type f -name "file.txt")

The above used GNU awk for nextfile.

How can I avoid no input files error from sed, when run from xargs?

If you want to avoid running sed when grep produces no output, then (since you've tagged this with Ubuntu), you can give the -r or --no-run-if-empty argument to xargs:

--no-run-if-empty

-r

If the standard input does not contain any nonblanks, do not run the command. Normally, the command is run once even if there is no input. This option is a GNU extension.

So your command should look like:

grep -rlZ "$old" /etc | xargs -0 -r sed -i "s/$old/$new/g"

(I added grep -Z and xargs -0 flags, since these are supported on your platform, and they make the commands more robust to malicious filenames)


For platforms without xargs -r, then the usual solution is to pass /dev/null as a first filename argument:

grep -rl "$old" /etc | xargs sed -i "s/$old/$new/g" /dev/null

In this case, when there are no matches, sed will operate harmlessly on the null device.

Using touch and sed within a find -ok command

This find with bash parameter-expansion will do the trick for you. You don't need sed at all.

find . -type f -name "*.wav" -exec sh -c 'x=$1; file="${x##*/}"; woe="${file%.*}"; touch "${woe}.txt"; ' sh {} \;

The idea is the part

  • x=$1 represents each of the entry returned from the output of find
  • file="${x##*/}" strips the path of the file leaving only the last file name part (only filename.ext)
  • The part woe="${file%.*}" stores the name without extension, and the new file is created with an extension .txt from the name found.

EDIT

Parameter expansion sets us free from using Command substitution $() sub-process and sed.

After looking at sh man page, I figured out that the command up above could be simplified.

Synopsis -c [-aCefnuvxIimqVEbp] [+aCefnuvxIimqVEbp] [-o option_name] [+o option_name] command_string [command_name [argument ...]]

...

-c Read commands from the command_string operand instead of from the stan‐dard input. Special parameter 0 will be set from the command_name oper‐and and the positional parameters ($1, $2, etc.) set from the remaining argument operands.

We can directly pass the file path, skipping the shell's name (which is useless inside the script anyway). So {} is passed as the command_name $0 which can be expanded right away.

We end up with a cleaner command.

find . -name *.wav -exec sh -c 'touch "${0%.*}".txt ;' {} \;

ls: not found after running read PATH

The variable name PATH is already reserved for a different purpose: It lists all the possible locations searched to find commands not built into the shell.

ls is such a command. Thus, when you change the value of PATH, you change the way the shell tries to look for the ls executable; unless the new value of PATH includes a directory with a ls executable in it, any further attempts to run ls (or other commands not built into the shell) will fail.

Instead, use a different variable name -- ideally, including at least one lower-case character, to avoid conflict with (all-uppercase) builtins and environment variables.


Thus, one corrected form might be:

#!/system/bin/sh 
echo "enter directory for listing"
IFS= read -r path

ls -R -- "$path" > list.txt

Note that the -R is moved before the "$path" in this case -- while GNU systems will allow optional arguments to be after positional arguments, many older UNIX systems will only treat flags (like -R) as valid if they're found before the first non-flag/option argument.

Find and replace over multiple lines using sed in Xcode Run Script bin/sh

Geek uses python to do this kind of thing to TMX map files. Just an option to consider.

Something like this (but iterating all files in directory etc), and save it as a .sh file:

#!/usr/bin/env python

import re

#you'd open a file and read in the tile properties thing
fakeTileProperties = "<tileproperties>1</tileproperties>\r"

f = open( "file1.tmx", "rU")
fo = open( "outputfile.tmx", "wc");

#read source file
s = f.read();

#find what you need
m = re.search("([\W\w]*)(<tileset firstgid=\"1\"[\W\w]*)(<layer name=\"background\"[\W\w]*)", s )

#write out to source file
fo.write(m.group(1))
fo.write(fakeTileProperties)
fo.write(m.group(3));

f.close();
fo.close();

print "done!"

The code handles content before the tile set firstgid="1" just in case there is some.

To use a script like this in Xcode 4 do the following:

  • put your script in a file next to your project file, name it myscript.py
  • use chmod +x myscript.py to make the script file executable.
  • in your Xcode project select the project and target and "Build Phases" tab and then create a new "Run Script" build phase.
  • leave the default shell of /bin/sh
  • put the following into the script field: $(SOURCE_ROOT)/myscript.py

Then when you do a build you should see the python script get executed. You can do a really simple test python file to test this (I just did):

#!/usr/bin/env python

print 'hello from python!'

note that the setting in the Run Script setup "Show Environmental variables in build log" is very helpful for getting the environmental variables like SOURCE_ROOT and such to locate your files.

good luck!



Related Topics



Leave a reply



Submit