Hot answers tagged

117

$ echo 192.168.1. | xargs -I{} grep {} *.txt Example Sample files: $ cat {1..3}.txt 192.168.1 192.168.1 192.168.1 Example run: $ echo 192.168.1. | xargs -I{} grep {} *.txt 1.txt:192.168.1. 2.txt:192.168.1. 3.txt:192.168.1.


82

You are almost there. In your last command, you can use -I to do the ls correctly -I replace-str Replace occurrences of replace-str in the initial-arguments with names read from standard input.  Also, unquoted blanks do not terminate input items; instead the separator is the newline character.  Implies -x and -L 1. So, with find . -type ...


55

Look at Stephane's answer for the best method, take a look at my answer for reasons not to use the more obvious solutions (and reasons why they are not the most efficient). You can use the -I option of xargs: find /tmp/ -ctime -1 -name "x*" | xargs -I '{}' mv '{}' ~/play/ Which works in a similar mechanism to find and {}. I would also quote your -name ...


54

Putting multiple jobs in the background is a good way of using the multiple cores of a single machine. parallel however, allows you to spread jobs across multiple servers of your network. From man parallel: GNU parallel is a shell tool for executing jobs in parallel using one or more computers. The typical input is a list of files, a list of ...


47

You may benefit from the -p or -t flags. xargs -p or xargs --interactive will print out the command to be executed and then prompt for input (y/n) to confirm before executing the command. % cat list one two three % ls list % cat list | xargs -p -I {} touch {} touch one ?...y touch two ?...n touch three ?...y % ls list one three xargs -t or xargs --...


37

Just write {} two times in your command. The following would work: $ echo test | xargs -I {} echo {} {} test test Your problem is how the commands are nested. Lets look at this: echo test | xargs -I {} echo {} && echo {} bash will execute echo test | xargs -I {} echo {}. If it runs successfully, echo {} is executed. To change the nesting, you ...


36

Try exporting function, then calling it in a subshell: showword() { echo $1 } export -f showword echo This is a sample message | xargs -d' ' -t -n1 -P2 bash -c 'showword "$@"' _


36

While you already know how you should solve your current problem, I'll still answer about xargs. xargs puts the string it got in the end of command, while in your case you need that string before the last argument of cp. Use -I option of xargs to construct the command. Like this: ls /source/path/*pattern* | xargs -I{} cp -u {} /destination/path In this ...


36

I believe that you can’t use -I that way.  But you can get the effect / behavior you want by saying: echo {1..8} | xargs -n2 sh -c 'echo "the number $1 comes before $2"' sh This, essentially, creates an ad hoc one-line shell script, which xargs executes via sh -c.  The two values that xargs parses out of the input are passed to this “script”.  The shell ...


35

You can use -I to define a place-holder which will be replaced with each value of the arguments fed to xargs. For example, ls -1 | xargs -I '{}' echo '{}' will call echo once per line from ls's output. You'll often see '{}' used, presumably because it's the same as find's place-holder. In your case, you also need to pre-process file's output to extract ...


30

Yes it can, with the unimaginatively named cat command: $ cat *csv > all.csv cat does what it says on the bottle, it conCATenates its input and prints to standard output. The command above will give an error if a file called all.csv already exists in the target directory: $ cat *csv > all.csv cat: all.csv: input file is output file You can safely ...


29

If you want that last 10 lines: tail myFile.txt | tr '\n' '\0' | xargs -r0i myCmd {} arg1 arg2 But with GNU xargs, you can also set the delimiter to newline with: tail myFile.txt | xargs -ri -d '\n' myCmd {} arg1 arg2 (-0 is short for -d '\0'). Portably, you can also simply escape every character: tail myFile.txt | sed 's/./\\&/g' | xargs -I{} ...


29

You can use standard globbing on the rm command: rm -- *\ * This will delete any file whose name contains a space; the space is escaped so the shell doesn't interpret it as a separator. Adding -- will avoid problems with filenames starting with dashes (they won’t be interpreted as arguments by rm). If you want to confirm each file before it’s deleted, add ...


28

if you want xargs to ignore quotes one of the good soultion can be the use of xargs flag xargs -0 Directly from Man page OPTIONS OPTIONS -0, --null Input items are terminated by a null character instead of by whitespace, and the quotes and backslash are not special (every character is taken literally). Disables the end of ...


26

That && is not part of the xargs command, it's a completely separate invocation. I think you'll want to explicitly execute a subshell: echo 95 | xargs -n1 -I_percent -- sh -c '[ _percent -ge 95 ] && echo "No Space on disk _percent% full -- remove old backups please"' Note also I'm using _percent instead of {} to avoid extra quoting ...


25

"with names read from standard input" means that xargs takes the data coming in on its standard input, splits it up, and uses it to run the command given in its arguments. By default, it splits on blanks or newlines, and runs echo with as many arguments at a time as possible. The -0 option in your example instructs xargs to split its input on null bytes ...


24

Because Vim is invoked from inside the pipeline, the stdin is connected to the previous pipeline's output, not the terminal. As an interactive command, Vim needs to receive its input from the terminal. Better avoid the pipe, e.g. via $ vim $(grep -rl test .) or from inside Vim: :args `grep -rl test .`


21

The history command just operates on your history file, $HISTFILE (typically ~/.history or ~/.bash_history). It'll be much easier if you just remove the lines from that file, which can be done many ways. grep is one way, but you have to be careful not to overwrite the file while still reading it: $ grep -v searchstring "$HISTFILE" > /tmp/history $ mv /...


21

GNU head and tail since coreutils version 8.25 have a -z option for that. With older versions or for non-GNU systems, you can try and swap \0 and \n: find ... -print0 | tr '\0\n' '\n\0' | head | tr '\0\n' '\n\0' Note that some head implementations can't cope with NUL characters (and they're not required to by POSIX), but where find supports -print0, ...


21

If you're using GNU xargs, there's --process-slot-var: --process-slot-var=environment-variable-name Set the environment variable environment-variable-name to a unique value in each running child process. Each value is a decimal integer. Values are reused once child processes exit. This can be used in a rudimentary load distribution scheme, for ...


20

Below are a dozen or so examples of how you can take a file such as this: $ cat k.txt 1 2 3 and convert it to this format: 1,2,3 You can use this command to create the above file if you'd like to play along: $ cat <<EOF > k.txt 1 2 3 EOF The examples below are split into 2 groups. Ones that "work" and ones that "almost" work. I leave these ...


19

With GNU tools: find /tmp/ -ctime -1 -name 'x*' -print0 | xargs -r0 mv -t ~/play/ The -t (--target) option is GNU specific. -print0, -r, -0, while non-standard and originating in GNU are also found in some other implementations like on some BSDs. POSIXly: find /tmp/ -ctime -1 -name 'x*' -exec sh -c ' exec mv "$@" ~/play/' sh {} + Both run as few mv ...


19

This should equally work as well: s1 | xargs -d "," -n1 s2 Test case: printf 1,2,3,4 | xargs -d ',' -n1 echo Result: 1 2 3 4 If s1 outputs that list followed by a newline character, you'd want to remove it as otherwise the last call would be with 4\n instead of 4: s1 | tr -d '\n' | xargs -d , -n1 s2


17

I found another solution in the manpage: explicitly specify delimiter to be '\n'. This turns off special handling for quotes: --delimiter=delim, -d delim Input items are terminated by the specified character. The specified delimiter may be a single character, a C-style character escape such as \n, or an octal or hexadecimal escape code. Octal ...


17

I had a similar requirement and ended up using the -I switch to have a placeholder and I was able to quote it. find . -size +1M | xargs -I {} rm "{}"


17

I would avoid parsing ls output Why not : find . -type f -name '* *' -delete No problem with rm :-). Although this is recursive and will delete all files with space in current directory and nested directories, as mentionned in comments.


17

Just tack the exit status check after grep, it will always get the exit status from the last command of the pipeline by default: sudo dmidecode | grep -q ThinkPad; echo $? Use -q to suppress any output from grep as we are interested in exit status only. You can use command grouping if you fancy, but this is somewhat redundant here: sudo dmidecode | { ...


17

With -I, xargs gets one argument per line as opposed to the default of one argument per (blank or newline delimited, possibly quoted) word without -I (and implies -n). So in your example date is called only once with {} expanded to the whole output of echo (which is on one line), minus the trailing newline. Here you can do (note that that -d is a GNU ...


16

The second example: find . -name '*.txt' -print0 | xargs -0 cat > out.txt Is completely legal and will recreate the file, out.txt each time it's run, while the first will concatenate to out.txt if it runs. But both commands are doing essentially the same thing. What's confusing the issue is the xargs -0 cat. People think that the redirect to out.txt is ...


16

If I understand correctly, you want to fire up one instance flac … | lame … for each input line, and interpolate the input into the arguments to both commands. Since you need xargs to start a pipeline, you need to make it start a program that's capable of creating pipelines, i.e. a shell. inotifywait -m -r -q -e moved_to --format "%w%f" ~/test | xargs -l ...


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