How to print the FontResourceDir with GhostScript (gs)? - ghostscript

I need my script to be able to figure out, where the Fontmap.GS resides in a given GhostScript installation -- so that it can be modified.
I used to rely on the output of gs -h for this, but the format of that changed between versions -- and was clumsy to begin with.
I'm quite certain, gs can be asked to print it (to stdout) neatly, but I don't know PostScript, unfortunately. I tried:
%!
FontResourceDir ==
which simply does not work: Error: /undefined in FontResourceDir. I'm sure, I'm very close to the solution -- please, help. Thank you.

You can use ghostscript to find the location of its Resource files. Fontmap.GS appears to be in the /Init subdirectory of the Resources.
/Font /Category findresource
begin
/ 128 string ResourceFileName =
% ^
% | n.b. this is SLASH followed by SPACE.
% We're feeding an "empty" name to ResourceFileName
end
This prints (for me): /usr/share/ghostscript/9.06/Resource/Font/
So, this pipe command should do the trick (until it changes again!)
echo /Font /Category findresource begin / 128 string ResourceFileName = | \
gsnd -q - | \
sed 's/Font\/$/Init\/Fontmap.GS/'

Related

For loop within a for loop for iterating files of different extensions

Say I have 20 different files. First 10 files end with .counts.tsv and the rest of the files end with .libsize.tsv. For each .counts.tsv there are matching .libsize.tsv files. I would like to use a for loop for selecting both of these files and run an R script for on those two files types.
Here is what I tried,
#!/bin/bash
arti='/home/path/tofiles'
for counts in ${arti}/*__counts.tsv ; do
for libsize in "$arti"/*__libsize.tsv ; do
Rscript score.R ${counts} ${libsize}
done;
done;
The above shell script iterates over the files more than 200 times whereas I have only 20 files. I need the Rscript to be executed 10 times for both files. Any suggestions would be appreciated.
I started typing up an answer before seeing your comment that you're only interested in a bash solution, posting anyway in case someone finds this question in the future and is open to an R based solution.
If I were approaching this from scratch, I'd probably just use an R function defined in the file that takes the two file names instead of messing around with the system() calls, but this would provide the behavior you desire.
## Get a vector of files matching each extension
counts_names <- list.files(path = ".", pattern ="*.counts.tsv")
libsize_names <- list.files(path = ".", pattern ="*.libsize.tsv")
## Get the root names of the files before the extensions
counts_roots <- gsub(".counts.tsv$", "",counts_names)
libsize_roots <- gsub(".libsize.tsv$", "",libsize_names)
## Get only root names that have both file types
shared_roots <- intersect(libsize_roots,counts_roots)
## Loop through the shared root names and execute an Rscript call based on the two files
for(i in seq_along(shared_roots)){
counts_filename <- paste0(shared_roots[[i]],".counts.tsv")
libsize_filename <- paste0(shared_roots[[i]],".libsize.tsv")
Command <- paste("Rscript score.R",counts_filename,libsize_filename)
system(Command)
}
Construct the second filename with ${counts%counts.tsv} (remove last part).
#!/bin/bash
arti='/home/path/tofiles'
for counts in ${arti}/*__counts.tsv ; do
libsize="${counts%counts.tsv}libsize.tsv"
Rscript score.R "${counts}" "${libsize}"
done
EDIT:
Less safe is trying to make it an oneliner. When the filenames are without spaces and newlines, you can risk an accident with
echo ${arti}/*counts.tsv ${arti}/*.libsize.tsv | xargs -n2 Rscript score.R
and when you feel really lucky (with no other files than those tsv files in $arti) make a bungee jump with
echo ${arti}/* | xargs -n2 Rscript score.R
Have you tried list.files in base? This will allow you to use all files in the folder.
arti='/home/path/tofiles'
for i in list.files(arti) {
script
}
See whether the below helps.
my_list = list.files("./Data")
counts = grep("counts.tsv", my_list, value=T)
libsize = grep("libsize.tsv", my_list, value=T)
for (i in seq(length(counts))){
system(paste("Rscript score.R",counts[i],libsize[i]))
}
Finally,
I tried the following and it helped me,
for sam in "$arti"/*__counts.tsv ; do
filebase=$(basename $sam)
samples=$(ls -1 ${filebase}|awk -F'[-1]' '{print $1}')
Rscript score.R ${samples}__counts.tsv ${samples}__libsize.tsv
done;
For someone looking for something similar :)

PDF to JPEG conversion using Ghostscript

I'm using Ghostscript to convert my PDF files to JPEGs with Ghostscript which works great.
For my output images I'm using %03d in the file name, so the file names come out 001, 002 ... and so on according to the page numbers.
But i want in some case the numbers to start from an higher number.
For example I process a file with two pages so the output images are page001.jpg, page002.jpg
Now I want to process another PDF and instead of replacing those files, I want to create page003.jpg, page004.jpg.
How can this be done?
This is my full command line I'm using now:
'C:\gs\gs9.14\bin \gswin64c -dNOPAUSE -sDEVICE=png16m \
-sOutputFile=page-%03d.jpg -r100x100 -q' . $pdf_file. '-c quit'
Here is a workaround trick, that you could use:
gswin64c.exe ^
-sDEVICE=png16m ^
-sOutputFile=page-%03d.jpg ^
-r100x100 ^
-c "showpage showpage" ^
-f filename.pdf
The -c "showpage showpage" inserts two empty pages into the output. The output files will be named
page-001.jpg + page-002.jpg + page-003.jpg + page-004.jpg
So the first two are white-only JPEGs and should be deleted afterwards.
You can extend this command with any number of empty pages you want.
Update
Of course, if you know in advance that you want to convert several different PDF files to images where you want the counting for a new PDF to continue exactly from where the last PDF ended, you could do this:
gswin64c.exe ^
-sDEVICE=jpeg ^
-sOutputFile=page-%03d.jpg ^
-r100x100 ^
-f file1.pdf ^
-f file2.pdf ^
-f file3.pdf ^
-f [...]
BTW, your original command requests .jpg file suffixes, while the Ghostscript device is png16m. This doesn't match. Initially I blindly copied your command, but now I've corrected it.
You cannot do that with the standard version of Ghostscript, the output file numbers are given as the emitted page number (so if you had a 10 page file, with /NumCOpies 2, you would get files numbered 0 to 19).
Of course, you can process the two files on the same command line, I think that will give you the second file with page numbers beginning where the first set left off.
Otherwise you will have to modify the source code of the Ghostscript device.

Call script on all file names starting with string in folder bash

I have a set of files I want to perform an action on in a folder that i'm hoping to write a scipt for. Each file starts with mazeFilex where x can vary from any number , is there a quick and easy way to perform an action on each file? e.g. I will be doing
cat mazeFile0.txt | ./maze_ppm 5 | convert - maze0.jpg
how can I select each file knowing the file will always start with mazeFile?
for fname in mazeFile*
do
base=${fname%.txt}
base=${base#mazeFile}
./maze_ppm 5 <"$fname" | convert - "maze${base}.jpg"
done
Notes
for fname in mazeFile*; do
This codes starts the loop. Written this way, it is safe for all filenames, whether they have spaces, tabs or whatever in their names.
base=${fname%.txt}; base=${base#mazeFile}
This removes the mazeFile prefix and .txt suffix to just leave the base name that we will use for the output file.
./maze_ppm 5 <"$fname" | convert - "maze${base}.jpg"
The output filename is constructed using base. Note also that cat was unnecessary and has been removed here.
for i in mazeFile*.txt ; do ./maze_ppm 5 <$i | convert - `basename maze${i:8} .txt`.jpg ; done
You can use a for loop to run through all the filenames.
#!/bin/bash
for fn in mazeFile*; do
echo "the next file is $fn"
# do something with file $fn
done
See answer here as well: Bash foreach loop
I see you want a backreference to the number in the mazeFile. Thus I recommend John1024's answer.
Edit: removes the unnecessary ls command, per #guido 's comment.

Is this (simple) for loop doing what I want it to?

I have pretty much no experience with cygwin & UNIX but need to use it for extracting a large set of data from a even larger set of files...
I had some help yesterday to do this short script, but (after running for ~7-8 hours) the script simply wrote to the same output file 22 times. Atleast that's what I think happened.
I've now changed the code to this (see below) but it would be really awesome if someone who knows how this is done properly could tell me if it's likely to work before I waste another 8 hours...
for chr in {1..22}
do
zcat /cygdrive/g/data/really_long_filename$chr | sed '/^#/d' | cut -f1-3 >> db_to_rs_$chr
done
I want it to read file 1..22, remove rows starting with #, and send columns 1 to 3 to a file ending with the same number 1..22
yesterday the last part was just ...-f1-3 >> db_to_rs which I suspect just rewrote that file 22 times?
Help is much appreciated
~L
Yes, the code would work as expected.
When the command ended in ...-f1-3 >> db_to_rs, it essentially appended all the output to the file db_to_rs.
Saying ... >> db_to_rs_$chr would create filenames ending in {1 .. 22}.
However, note that saying >> would append the output to a file. So if db_to_rs1 already exists, the output would be appended. If you want to create a new file instead, say > instead of >>.

unrar.exe and | pipe on windows

I just downloaded the freeware unrar.exe from winrar website. If, from the command line, you tipe
unrar.exe p -inul myarchive.rar
It "prints" out to default std the content of my archive. Since the archive is just one .avi file, if I do:
unrar.exe p -inul myarchive.rar > output.avi
It works perfectly. Now, I'd need to redirect the output std of this program to the input std on a program of mine. This means that I do:
unrar.exe p -inul myarchive.rar | myprogram.exe
myprogram.exe is just a simple c file that every second (this means: very slowly) reads a char from standard input and prints it to screen.
After approximately 10000 chars, I get only the -1 byte (FF in hexadecimal representation).
Why this? How can I solve this problem?

Resources