1

OS: aix shell: bsh

Hi, ppl

I have two types of files, one type ends with .pdf.marker and the other ends with .pdf

There should be always a pair with the same name (only the extensions are different).

When I move a .pdf.marker file I must also move its corresponding .pdf file.

I tried something like this:

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file mv file ${OUTPUT_LOCATION}/. mv $(basename file .marker) ${OUTPUT_LOCATION}/. 

Then I read this: xargs with multiple commands as argument and tried something like this:

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file {mv file ${OUTPUT_LOCATION}/.; mv $(basename file .marker) ${OUTPUT_LOCATION}/.;} 

but it still didnt work.

I just need to execute 2 commands after xargs.

EDIT

Following the proposed answers I got i tried to put just 2 parameters into one move command instead of two separate move commands following xargs.

find ${INPUT_LOCATION}/ -name "*.pdf.marker" | xargs -I file mv file $(basename file .marker) ${OUTPUT_LOCATION}/. 

But now, the .pdf.marker is moved first, then when I try to remove the .marker from the filename to get the .pdf filename i get a warning no such file or directory.

Is there another way to get .pdf filename string?

SOLUTION

find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;

Moved 200 000 files in cca. 25 min. without problems.

Thanks everyone who participated with their answers and a big thanks goes to you Nahuel Fouilleul!

Community
  • 1
  • 1
Mandark
  • 798
  • 1
  • 12
  • 33

5 Answers5

3

You could try something like the following:

find ${INPUT}/ -name "*.pdf" -exec mv '{}' '{}'.marker ${OUTPUT} \;

To test if the marker file exists you could use something like the following:

find ${INPUT}/ -name "*.pdf" -exec test -e '{}'.marker \; -exec mv '{}' '{}'.marker ${OUTPUT} \;
Ortwin Angermeier
  • 5,957
  • 2
  • 34
  • 34
  • i am only allowed to move a **.pdf** file if the **.pdf.marker** file exist and only then. So I need to use the **basename** command on the **.pdf.marker** file – Mandark Jul 11 '12 at 09:30
  • i updated my answer, now only the pdf files with a marker file will be moved. – Ortwin Angermeier Jul 11 '12 at 10:09
2

try this (x option for debug)

find "${INPUT_LOCATION}" -name '*.pdf.marker' | xargs -i bash -cx 'pdf=`dirname {}`/`basename {} .marker`;[ -e "$pdf" ]&&{ mv {} "$pdf" "$0";}' "${OUTPUT_LOCATION}"

or shorter

find $INPUT_LOCATION -name '*.pdf.marker' | xargs -i bash -c 'mv ${0%.marker} $0 $1' {} $OUTPUT_LOCATION

or

find $INPUT_LOCATION -name '*.pdf.marker' -exec bash -c 'mv ${0%.marker} $0 $1' {} $OUTPUT_LOCATION \;

maybe more standard

find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;

and for tests echo can be added

find ${INPUT_LOCATION} -name '*.pdf.marker' -exec sh -c 'echo mv $0 `dirname $0`/`basename $0 .marker` $1' {} ${OUTPUT_LOCATION} \;
Nahuel Fouilleul
  • 18,726
  • 2
  • 31
  • 36
  • Your middle answer did the trick for me. Thanks :) I just have one more question, perhaps you'll know; the script is running under **aix** and will be executed via **bsh**, will the ...xargs -i **bash** -c 'mv.... make problems? In my testing enviroment I have **bash** but on the production enviroment(which I'm forbidden to access) its **bsh**. – Mandark Jul 11 '12 at 10:53
  • variable substitution ${VAR%pat} may not work with bsh so the first answer is more standard sh but maybe with -f instead of -e – Nahuel Fouilleul Jul 11 '12 at 11:00
  • the 4th(more standard version) says **find missing argument '-exec'** – Mandark Jul 11 '12 at 11:11
  • Yes, it works quite good even for 25k files, but it doesn't use **xargs** anymore. I will probably use your version, but I must be cautious because when we used **ls** command in conjuction with a **for loop** without **xargs** we got an error like Argument list too long for a large number of files cca. 15k – Mandark Jul 11 '12 at 12:26
  • the problem with ls is the shell expansion of * this is not the case with find because the * is between quotes there is no shell expansion to see the difference `echo '*.pdf.marker'` and `echo *.pdf.marker` – Nahuel Fouilleul Jul 11 '12 at 16:14
1

No need to use xargs:

for i in `find ${INPUT_LOCATION} -name \*.pdf`; do mv $i ${OUTPUT_LOCATION}; mv $i.marker ${OUTPUT_LOCATION}; done
Jenny D
  • 1,225
  • 9
  • 20
0
for f in *.pdf.marker; do
  if [ -e "${f%.marker}" ]; then
    mv "$f" "${f%.marker}" "$OUTPUT_LOCATION"
  fi
done
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
0

If you have GNU Parallel installed:

find ${INPUT_LOCATION} -name '*.pdf.marker' | parallel mv {} {.} ${OUTPUT_LOCATION}

To learn more watch the intro videos: http://pi.dk/1

Ole Tange
  • 31,768
  • 5
  • 86
  • 104