![]() |
removing selected files
Hello all,
I should like to know if there's a purely Bash solution to this scripting problem (I know how to solve it using an OCaml-created executable, but that's heavy somehow...) Given a directory, erase the PDF files in it coming from a TEX or LATEX file (in other words, erase only the files whose names ends in .pdf, and erase xyz.pdf only when xyz.tex exists in the directory). Ewan |
Code:
#!/bin/bash// Tony |
This works, except that
Code:
basename -s txtCode:
basename -s texCode:
*.PDFCode:
*.pdfwith what should I replace "for i in *.PDF" ? Does "for i in *.pdf *.PDF" work ? Ewan Quote:
|
Actually Ewan, it should be 'basename -s pdf' - I forgot that line when I was translating from another script.
I also got the test wrong - it should be [ -a $dname ] Covering both PDF and pdf is harder - this should do it. Code:
#!/bin/bash// Tony |
Quote:
The -f you had before was just fine. Quote:
Quote:
Quote:
The trick is to quote the "$dname" variable when it gets used. Note: the dname variable from your first post (after if [ -f) was missing the $ prefix to make it a variable. So if [ -f dname ] would always fail (unless some file named "dname" was present). Quote:
-- If case doesn't matter (i.e., only lowercase .pdf files will exist), then this is good enough: x=.pdf y=.tex; for i in *$x; do [[ -f `basename -s $x "$i"`$y ]] && ls "$i"; done [i used the x and y variables to make the script more easily adaptable.] If both .pdf and .PDF items need handling, then more syntax is required: xa=.pdf xb=.PDF y=.tex; for i in *$xa; do [[ -f `basename -s $xa "$i"`$y || -f `basename -s $xb "$i"`$y ]] && ls "$i"; done Note: oddball 'mixed-case' instances (like .Pdf) will go undetected. Naturally, change the ls command to rm once you're satisfied it works. I'm fairly certain it won't trip over any spaces in filenames. But, i didn't test for all potential filename gotchas (such as quotes, slashes and various other hazardous punctuation). -HI- |
No, I tested it quickly. It was a conversion from a script I used for something similar and the cut and paste wasn't perfect - my version has the closing backtick.
I was actually thinking after I posted that I had it backwards - if the case of the .tex files is always correct then the smart way would be to loop through those and then just change the rm to 'rm "${base}[Pp][Dd][Ff]"' and cover all the cases. There is s good case for basename -s having a case insensitive option <g>. // Tony |
Quote:
Code:
$ mkdir testd; cd testd; touch test.tEx; ls[Though, hopefully that extreme is never needed... i prefer the flexibility of those x and y variables, for simple script alteration. Then again, if it's always gonna be pdf files... sure, why not.] Quote:
|
Actually, it seems your solution is not working Hal : when I tried it on my
files, I got error messages indicating that the basename command was used with an incorrect syntax (although I can't figure out why). Is there a special reason you use a && instead of a "if" construct (which seemed more natural to me in this case?) Ewan |
Quote:
(EDIT: only works with .tex and .pdf -- i.e. not .PdF .Tex etc) (EDIT 2: updated code at end) Code:
for i in *.tex ; doEDIT 2: the following code works for *.TeX, *.PDf, etc: Code:
for i in *.[tT][eE][xX] ; do |
Quote:
BTW, what Mac OS and Bash versions are you running? Quote:
|
Quote:
// Tony |
Quote:
Apologies Hal, your solution did work but a character slipped in my copy/paste and I didn't notice ... The use of "%" in FingerEater's solution is terser and better (I think) than invoking the basename command. I had never read about this use of "%" in Bash before. Is there a site where it is explained in more detail (not the Bash manual ...) ? For the record, below is the script I finally wrote to get rid of some files produced by pdflatex, not only in the current directory but also in any subdirectory : Code:
for ff in `find . -name *.tex`; |
Quote:
file:///usr/share/doc/bash/bashref.html#SEC30 Else, google for "Shell Parameter Expansion". |
Quote:
for i in *.tex Quote:
From what i can see, this works perfectly (even with weird 'mixed-case' files): for i in *.tex; do ls "${i%.*}".[Pp][Dd][Ff]; done Does that **not** work for someone? (Show me listing and session). Gotta admit, i considered a shell parameter expansion solution at first... but i was unable to put it together so cleverly, the way you did. Ironically, roparzhhemon likes it (and so do i) because it's "terser and better". So... what happened to "natural" then? :D |
Quote:
while that script does find tex files everywhere in the hierarchy... the only pdf, aux, log, and dvi files it's looking at (for comparison purposes) are in the top level of the current working directory. |
Quote:
Code:
Test $> echo $BASH_VERSIONQuote:
Code:
Test $> lsBut, (a modified version of) the code I gave produces: Code:
Test $> lsCode:
Test $> ls |
Quote:
You were right. I'm liking this now: for i in *.tex; do [ -f "${i%.[Tt][Ee][Xx]}".pdf ] && ls "${i%.*}".[Pp][Dd][Ff]; done Strictly speaking, the final [Pp][Dd][Ff] isn't needed (pdf will do). But, it's nice to see it list the file using the exact case of the file. |
Quote:
Code:
Test $> for i in *.tex; do [ -f "${i%.[Tt][Ee][Xx]}".[Pp][Dd][Ff] ] && ls "${i%.*}".[Pp][Dd][Ff]; doneCode:
Test $> for i in *.tex; do [ -f "${i%.[Tt][Ee][Xx]}".pdf ] && ls "${i%.*}".[Pp][Dd][Ff]; done |
Quote:
Is your disk formatted as a case-sensitive filesystem perhaps? Very few people do that. Quote:
Code:
$ for i in *.[Tt][Ee][Xx]; do echo "$i"; doneIf your Mac can't reproduce that output, then your filesystem must be case sensitive. Quote:
|
Quote:
Quote:
EDIT: Output from diskutil in Terminal Code:
$> diskutil info /EDIT: Upon further reading, the bash shell seems to be case-sensitive, but can be told to be case-insensitive. Hal, you don't happen to have the 'nocaseglob' option set, do you? (e.g. in your .bashrc or .bashprofile files) If I set that option, I get the output you get: Code:
Test $> shopt -s nocaseglob |
Hmm, you know what? At this point, an extra 9 chars which make a script work for both case-sensitive and case-insensitive filesystems? Fine, it's worth it. Let's not discuss it any further.
:) [kidding] Quote:
-- Do you use Adobe Products? (Creative Suite, etc.) I've read they bug-out on case sensitive filesystems. Then again, it's not 100% clear that's what you have. [Maybe start a new thread for this... i'm not sure.] |
Quote:
Did you see my (many) edits in the last post? I definitely don't have a case-sensitive system, but passing the 'nocaseglob' option to bash gets me the behaviour you have (i.e. bash is case-sensitive by default). Looks like 'nocaseglob' could be key... |
Quote:
Code:
$ shopt |grep glob<sigh> i hate unix. :D -- You're right, this one's more universal: for i in *.[Tt][Ee][Xx]; do [ -f "${i%.*}".pdf ] && ls "${i%.*}".[Pp][Dd][Ff]; done [now i have to find that thread at ars technica where i got mislead last spring... it's probably locked. ;-) ] |
Quote:
Quote:
|
Quote:
Code:
bind 'set completion-ignore-case'The trick is to remember that you've done it. Unix ought to have a "list all my customizations" command. Hmm... that shouldn't be too hard. Write a script to capture all settable options to a file: alias -p bind -pvs enable -p shopt -p set Generate the same file from a virgin install, and keep it around. (Such a file could be part of a virgin install. Or log in as Guest and run the script.) Use diff to find all the ways you're different. You'd probably also want to have a list of ignorable differences (like the value of $USER or $HOME). No... I will resist. (Another reason to hate unix -- it sucks you in by making everything seem so doable.) |
Quote:
bind 'set completion-ignore-case on' Not sure if that trailing "on" is redundant or what. [?] Can't remember where i dug that up. [i'd like to find a good tutorial on bind.] Quote:
|
Quote:
Quote:
|
| All times are GMT -5. The time now is 10:17 PM. |
Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.