{"id":8474,"date":"2019-01-22T22:42:36","date_gmt":"2019-01-22T22:42:36","guid":{"rendered":"https:\/\/www.appservgrid.com\/paw92\/?p=8474"},"modified":"2019-03-09T20:55:00","modified_gmt":"2019-03-09T20:55:00","slug":"command-line-tip-put-down-the-pipe","status":"publish","type":"post","link":"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/01\/22\/command-line-tip-put-down-the-pipe\/","title":{"rendered":"Command-Line Tip: Put Down the Pipe"},"content":{"rendered":"<p><img decoding=\"async\" src=\"https:\/\/www.linuxjournal.com\/sites\/default\/files\/styles\/360_250\/public\/nodeimage\/story\/bash-148836_960_720_13.png?itok=g7Bi8Aur\" alt=\"&quot;&quot;\" \/><\/p>\n<p><em>Learn a few techniques for avoiding the pipe and making your command-line commands more efficient.<\/em><\/p>\n<p>Anyone who uses the command line would acknowledge how powerful the pipe is. Because of the pipe, you can take the output from one command and feed it to another command as input. What&#8217;s more, you can chain one command after another until you have exactly the output you want.<\/p>\n<p>Pipes are powerful, but people also tend to overuse them. Although it&#8217;s not necessarily wrong to do so, and it may not even be less efficient, it does make your commands more complicated. More important though, it also wastes keystrokes! Here I highlight a few examples where pipes are commonly used but aren&#8217;t necessary.<\/p>\n<h3>Stop Putting Your Cat in Your Pipe<\/h3>\n<p>One of the most common overuses of the pipe is in conjunction with\u00a0<code>cat<\/code>. The\u00a0<code>cat<\/code>\u00a0command concatenates multiple files from input into a single output, but it has become the overworked workhorse for piped commands. You often will find people using\u00a0<code>cat<\/code>\u00a0just to output the contents of a single file so they can feed it into a pipe. Here&#8217;s the most common example:<\/p>\n<pre><code>\r\ncat file | grep \"foo\"\r\n<\/code><\/pre>\n<p>Far too often, if people want to find out whether a file contains a particular pattern, they&#8217;ll\u00a0<code>cat<\/code>\u00a0the file piped into a\u00a0<code>grep<\/code>\u00a0command. This works, but\u00a0<code>grep<\/code>\u00a0can take a filename as an argument directly, so you can replace the above command with:<\/p>\n<pre><code>\r\ngrep \"foo\" file\r\n<\/code><\/pre>\n<p>The next most common overuse of\u00a0<code>cat<\/code>\u00a0is when you want to sort the output from one or more files:<\/p>\n<pre><code>\r\ncat file1 file2 | sort | uniq\r\n<\/code><\/pre>\n<p>Like with\u00a0<code>grep<\/code>,\u00a0<code>sort<\/code>\u00a0supports multiple files as arguments, so you can replace the above with:<\/p>\n<pre><code>\r\nsort file1 file2 | uniq\r\n<\/code><\/pre>\n<p>In general, every time you find yourself catting a file into a pipe, re-examine the piped command and see whether it can accept files directly as input first either as direct arguments or as STDIN redirection. For instance, both\u00a0<code>sort<\/code>\u00a0and\u00a0<code>grep<\/code>\u00a0can accept files as arguments as you saw earlier, but if they couldn&#8217;t, you could achieve the same thing with redirection:<\/p>\n<pre><code>\r\nsort &lt; file1 file2 | uniq\r\ngrep \"foo\" &lt; file\r\n<\/code><\/pre>\n<h3>Remove Files without xargs<\/h3>\n<p>The\u00a0<code>xargs<\/code>\u00a0command is very powerful on the command line\u2014in particular, when piped to from the\u00a0<code>find<\/code>command. Often you&#8217;ll use the\u00a0<code>find<\/code>\u00a0command to pick out files that have a certain criteria. Once you have identified those files, you naturally want to pipe that output to some command to operate on them. What you&#8217;ll eventually discover is that commands often have upper limits on the number of arguments they can accept.<\/p>\n<p>So for instance, if you wanted to perform the somewhat dangerous operation of finding and\u00a0<em>removing<\/em>\u00a0all of the files under a directory that match a certain pattern (say, all mp3s), you might be tempted to do something like this:<\/p>\n<pre><code>\r\nfind .\/ -name \"*.mp3\" -type f -print0 | rm -f\r\n<\/code><\/pre>\n<p>Of course, you should\u00a0<em>never<\/em>\u00a0directly pipe a\u00a0<code>find<\/code>\u00a0command to remove. First, you should\u00a0<em>always<\/em>\u00a0pipe to\u00a0<code>echo<\/code>\u00a0to ensure that the files you are about to delete are the ones you want to delete:<\/p>\n<pre><code>\r\nfind .\/ -name \"*.mp3\" -type f -print0 | echo\r\n<\/code><\/pre>\n<p>If you have a lot of files that match the pattern, you&#8217;ll probably get an error about the number of arguments on the command line, and this is where\u00a0<code>xargs<\/code>\u00a0normally comes in:<\/p>\n<pre><code>\r\nfind .\/ -name \"*.mp3\" -type f -print0 | xargs echo\r\nfind .\/ -name \"*.mp3\" -type f -print0 | xargs rm -f\r\n<\/code><\/pre>\n<p>This is better, but if you want to delete files, you don&#8217;t need to use a pipe at all. Instead, first just use the\u00a0<code>find<\/code>\u00a0command without a piped command to see what files would be deleted:<\/p>\n<pre><code>\r\nfind .\/ -name '*.mp3\" -type f\r\n<\/code><\/pre>\n<p>Then take advantage of\u00a0<code>find<\/code>&#8216;s\u00a0<code>-delete<\/code>\u00a0argument to delete them without piping to another command:<\/p>\n<pre><code>\r\nfind .\/ -name '*.mp3\" -type f -delete\r\n<\/code><\/pre>\n<p>So next time you find your pinky finger stretching for the pipe key, pause for a second and think about whether you can combine two commands into one. Your efficiency and poor overworked pinky finger (whoever thought it made sense for the pinky to have the heaviest workload on a keyboard?) will thank you.<\/p>\n<p><a href=\"https:\/\/www.linuxjournal.com\/content\/put-down-pipe\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn a few techniques for avoiding the pipe and making your command-line commands more efficient. Anyone who uses the command line would acknowledge how powerful the pipe is. Because of the pipe, you can take the output from one command and feed it to another command as input. What&#8217;s more, you can chain one command &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.appservgrid.com\/paw92\/index.php\/2019\/01\/22\/command-line-tip-put-down-the-pipe\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Command-Line Tip: Put Down the Pipe&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-8474","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/8474","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/comments?post=8474"}],"version-history":[{"count":2,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/8474\/revisions"}],"predecessor-version":[{"id":11036,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/posts\/8474\/revisions\/11036"}],"wp:attachment":[{"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/media?parent=8474"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/categories?post=8474"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.appservgrid.com\/paw92\/index.php\/wp-json\/wp\/v2\/tags?post=8474"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}