LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 06-27-2013, 09:57 AM   #1
otaviolb
LQ Newbie
 
Registered: Oct 2012
Location: Minas Gerais, Brazil
Distribution: Opensuse and Debian
Posts: 13

Rep: Reputation: Disabled
xargs: placement of arguments


Problem statement: Given several files tmp1.pdf tmp2.pdf etc, build a single pdf:
Solution:
pdfunite tmp1.pdf tmp2.pdf ... final.pdf

But I don't want to type the n tmp files :-)

I am learning first with three files. After getting some feeling with the commands, I go further with several ones.

The simplest I could figure out:
Code:
$ls -l  |xargs -i pdfunite {} final.pdf
It fails. The reason I discover when I substitute echo for pdfunite:

Code:
$ls -l  |xargs -i echo {} final.pdf 
tmp1.pdf final.pdf
tmp2.pdf final.pdf
tmp3.pdf final.pdf
tmp4.pdf final.pdf
This is obviously wrong. Let try find:
Code:
$find . -maxdepth 1 -name tmp\*.pdf -print0
./tmp4.pdf./tmp1.pdf./tmp3.pdf./tmp2.pdf
I cannot figure out why it is out of order. This is not acceptable, the pages must be ordered. Try sort:

Code:
$find . -maxdepth 1 -name tmp\*.pdf -print0 | sort -z
./tmp1.pdf./tmp2.pdf./tmp3.pdf./tmp4.pdf
Fine. Let go on:

Code:
$find . -maxdepth 1 -name tmp\*.pdf -print0 | sort -z | xargs -0 -i echo {} final.pdf
./tmp1.pdf final.pdf
./tmp2.pdf final.pdf
./tmp3.pdf final.pdf
./tmp4.pdf final.pdf
No progress. I'm stuck. What do I need to know?

Operating sysyem: OpenSuse 12.3
 
Old 06-27-2013, 10:20 AM   #2
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware64-15.0
Posts: 6,376

Rep: Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756Reputation: 2756
At a bash command prompt
Code:
for i in tmp*.pdf; do list+=" $i"; done; pdfunite $list final.pdf
 
Old 06-27-2013, 12:13 PM   #3
tange
LQ Newbie
 
Registered: Jul 2010
Posts: 13

Rep: Reputation: 9
How about the obvious:
Code:
    pdfunite tmp*.pdf final.pdf
If you only have the files on stdin then you can do:
Code:
    ls | parallel -j1 -X pdfunite {} final.pdf
You can install GNU Parallel in 10 seconds:
Code:
    wget -O - pi.dk/3 | sh
 
Old 06-27-2013, 08:36 PM   #4
otaviolb
LQ Newbie
 
Registered: Oct 2012
Location: Minas Gerais, Brazil
Distribution: Opensuse and Debian
Posts: 13

Original Poster
Rep: Reputation: Disabled
Thank you alland and tange. Both techniques, loop and bash expansion work as long as tmp files are numbered with a single digit (1 to 9). Therefore, the proposed problem was solved.

However, if tmp files range to 10 or more, the first page after bash expansions is tmp10.pdf, then tmp1.pdf ... etc. In this case another approach must be chosen. Parallel I have not tried, just because, right now, I am trying to master xargs. BTW, thanks also for the nice script for installing parallel. I had never thought in running a script direct from the web via wget and sending it to sh. :-) Parallel is a tool I wish to master.

Posts with further suggestions using xargs would be appreciated, for learning purposes.
 
Old 06-28-2013, 05:26 AM   #5
tange
LQ Newbie
 
Registered: Jul 2010
Posts: 13

Rep: Reputation: 9
Quote:
Originally Posted by otaviolb View Post
However, if tmp files range to 10 or more, the first page after bash expansions is tmp10.pdf, then tmp1.pdf ... etc. In this case another approach must be chosen.
Assuming you have tmp1.pdf ... tmp100.pdf:
Code:
    pdfunite tmp{1..100}.pdf final.pdf
PS. To master GNU Parallel: Watch pi.dk/1 and read the examples https://www.gnu.org/software/paralle...ment_appending
 
Old 06-28-2013, 06:36 AM   #6
otaviolb
LQ Newbie
 
Registered: Oct 2012
Location: Minas Gerais, Brazil
Distribution: Opensuse and Debian
Posts: 13

Original Poster
Rep: Reputation: Disabled
It works. Thanks again, including for the tips.
 
Old 06-28-2013, 11:24 AM   #7
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
What you really should be using is standard shell globbing. That's the preferred way to build a command line with multiple files.

Beware though, as you've discovered, that the files will expand in ascii sorting order, which means that "10" will probably come just after "1", instead of "9". You have to get a bit fancy if you want to match non-zero-padded names with globs.

Code:
pdfunite tmp[1-9].pdf tmp1[0-9].pdf tmp2[0-9].pdf ... final.pdf
So you should really get into the habit of always zero-padding numbers in your filenames. "10" will always follow "09". With zero padding, the command would look like this (assuming 2 digits):

Code:
pdfunite tmp[0-9][0-9].pdf final.pdf
brace expansion, as tange posted above, can be used as well, and is a good way to deal with files that aren't zero-padded. It does have a drawback, however. Since the whole list of possible filenames is built first, any entries that don't match an actual filename will probably give you "file not found" errors.

globbing doesn't have this problem, as it only expands into files that actually exist. Do note however that if a glob matches nothing, the shell will try to use the raw string as is, unless the nullglob or failglob shell options are set.

Last edited by David the H.; 06-28-2013 at 11:36 AM. Reason: added code example
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
xargs: unmatched single quote; by default quotes are special to xargs unless you use Raakh5 Linux - Newbie 7 05-21-2014 07:26 PM
Can xargs's initial-arguments expand? virteman Linux - General 2 03-25-2009 03:58 AM
window placement jimerickso Ubuntu 2 09-29-2007 11:19 PM
Directory placement JROCK1980 Slackware 1 11-11-2003 11:09 PM
Windows Placement enlight1 Linux - Newbie 4 06-18-2003 12:26 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 04:04 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration