Skip to main content
use `cut` to remove initial directories
Source Link
JigglyNaga
  • 8.1k
  • 1
  • 28
  • 48

#The Problem

By default, find performs the -print action:

 -print

True; print the full file name on the standard output, followed by a newline.

The "full file name" means that you'll see the absolute path to each file:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

Using the basename

If you only want the file's basename (because all files are in the same source folder), you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

Using the relative name

Alternately (if the input files are in different directories), you will need to trim some of the directory path. You could use eg. cut for that:

find "/home/user/original" -type f -name *.pdf | cut -d/ -f5- | while read -r file
do
    gs [...] -sOutputFile="/home/user/processed/$file" "/home/user/original/$file"

This removes everything up to and including the 4th / of the input. However, it won't handle the creation of new output directories to match the structure of the input tree.

By default, find performs the -print action:

 -print

True; print the full file name on the standard output, followed by a newline.

The "full file name" means that you'll see the absolute path to each file:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

If you only want the file's basename (because all files are in the same source folder), you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

#The Problem

By default, find performs the -print action:

 -print

True; print the full file name on the standard output, followed by a newline.

The "full file name" means that you'll see the absolute path to each file:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

Using the basename

If you only want the file's basename (because all files are in the same source folder), you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

Using the relative name

Alternately (if the input files are in different directories), you will need to trim some of the directory path. You could use eg. cut for that:

find "/home/user/original" -type f -name *.pdf | cut -d/ -f5- | while read -r file
do
    gs [...] -sOutputFile="/home/user/processed/$file" "/home/user/original/$file"

This removes everything up to and including the 4th / of the input. However, it won't handle the creation of new output directories to match the structure of the input tree.

add more manpage excerpts; assumption that all files are in the same folder
Source Link
JigglyNaga
  • 8.1k
  • 1
  • 28
  • 48

By default, find outputsperforms the full filename of every match. That includes-print action:

 -print

True; print the full file name on the standard output, followed by a newline.

The "full file name" means that you'll see the absolute path to each file:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

If you only want the file's basename (because all files are in the same source folder), you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

By default, find outputs the full filename of every match. That includes the absolute path:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

If you only want the file's basename, you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).

By default, find performs the -print action:

 -print

True; print the full file name on the standard output, followed by a newline.

The "full file name" means that you'll see the absolute path to each file:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

If you only want the file's basename (because all files are in the same source folder), you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).
Source Link
JigglyNaga
  • 8.1k
  • 1
  • 28
  • 48

By default, find outputs the full filename of every match. That includes the absolute path:

/home/user/original/test001.pdf
/home/user/original/test002.pdf
...
/home/user/original/test999.pdf

So when you use

gs -sOutputFile="/home/user/processed$file"

...inside the loop, the variable $file contains /home/user/original/test001.pdf, and the whole expression expands to the two paths concatenated:

gs -sOutputFile="/home/user/processed/home/user/original/test001.pdf"

This is reflected by the error message you saw:

Could not open the file /home/user/processed/home/user/original/test001.pdf

If you only want the file's basename, you can tell find to use a different output format.

find "/home/user/original" -type f -name *.pdf -printf '%f\n'
   -printf format

True; print format on the standard output, interpreting `' escapes and `%' directives.

[...]

        \n     Newline.

        %f     File's name with any leading directories removed (only
                 the last element).