Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Can this be done more nicely (echo a placeholder for another command)

echo $(for x in *;do echo $x|sed 's/\([ \t\n\r\v\f\;#]\)/\^\1/g'|sed 's/$/\;/g';done)

Also, there should be no ; after the last filename.

example usage of the command 'doit' is

doit files[ list-of-files ] 'flags[foo;bar;other^ flag]options[value^ 1[1]value^ array[1;2;3]]'

etc.

It is possible to escape whitespace internally (in doit), since it does not affect the doits tokenizer (it just eats every whitespace not following ^). As well as the good extensibility of the syntax, the code for reading configuration files and the command line is the same.

The sed thing works expect that it adds a ; too much at the end. However, logic for adding ; inside doit is not hard to implement so this last step is not nessecary. What I dislike, is that I need a loop to escape each argument individually. Just echo * | sed ... would not do it since echo destroys information (printing everything delimited by whitespace).

Similar problem: I want to add echo ~/my_progs/* colon separated to the path variable.

share|improve this question
1  
Why not just fix the command to handle arguments properly in the first place? –  Ignacio Vazquez-Abrams Sep 4 '13 at 13:49
1  
Can you tell us what you really need to do or why you would need this? Like Ignacio said, this is probably a question of just interpreting the arguments correctly, not forcing them into some format. See also: mywiki.wooledge.org/XyProblem –  slhck Sep 4 '13 at 14:02
1  
Hm. It'd probably be easier if you could show us an example list of files and the exact format that this magical doit requires. Or is your command working perfectly already and you're just looking for something "nicer", because…? –  slhck Sep 4 '13 at 14:40
1  
As @slhck said, we will need an example of the input and expected output and, preferably, the elusive doit to answer you. –  terdon Sep 4 '13 at 14:59
1  
If its adding an extra ; just remove the last sed command: sed 's/$/\;/g'. You are explicitly telling it to add a ; at the end. There probably is a nicer way of doing this but we cannot find it unless you give us concrete examples. Up to you. –  terdon Sep 4 '13 at 16:49

2 Answers 2

up vote 1 down vote accepted

It's unclear what you are trying to do but based on "escaping list of files" I think this is the solution:

IFS=$(echo -en "\n\b");
for file in $list; do
  sed -i 's/before/after/g' "$file";
done;

Setting the environmental variable IFS (Internal File Separator) to that will correctly separate files based on line breaks.


Or possibly, use find if you don't want to use a loop.

doit() { find -name "$@" -exec sed -i 's/before/after/g' {} \; }
doit myfiles*txt
share|improve this answer

Well I wanted to do it directly in shell but compiling a C program works better. From the shell view this is a "quantum computer": One op that runs a lot faster than the shell script above. I guess it takes alot more time to spawn sed for each file.

#include <cstdio>

int main(int argc, char* argv[])
    {
    if(argc==0)
        {return -1;}
    --argc;
    ++argv;
    while(argc)
        {
        const char* arg=*argv;
        while(*arg)
             {
             if(*arg>='\0' && *arg<=' ')
                 {putchar('^');}
             switch(*arg)
                 {
                 case '[':
                 case ']':
                 case ';':
                 case '^':
                 case '#':
                     putchar('^');
                 }
             putchar(*arg);
             ++arg;
             }
         --argc;
         if(argc)
             {putchar(';');}
         ++argv;
         }
    return 0;
    }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.