renaming file error? - elisp

I have a function to compress my pdf file using pdftk:
(defun compresspdf (filename)
(interactive)
(let ((tmpfile (concat filename "~")))
(start-process-shell-command "pdftk" nil
(format "pdftk %s cat output %s compress dont_ask"
filename tmpfile))
(rename-file tmpfile filename t)))
It compresses the file and saves it as the same name with ~ appended. However, at the point where it's supposed to rename the file, it gives me an error:
let: Renaming: No such file or directory, /pathtofile/mypdf.pdf~, /pathtofile/mypdf.pdf, though clearly, both of these files exist. I can separately evaluate rename-file afterwards and it works fine. Maybe it's trying to rename the ~ file before it's actually created? In that case, how can I make it wait until the process is finished? (and possibly check for errors?)

As opposed to using 'start-process-shell-command, which just spawns the process, so the rename happens before the tmpfile is created. Try using 'shell-command, like so:
(defun compresspdf (filename)
(interactive)
(let ((tmpfile (concat filename "~")))
(with-temp-buffer
(shell-command (format "pdftk %s cat output %s compress dont_ask"
filename tmpfile)
(current-buffer)
(current-buffer)))
(rename-file tmpfile filename t)))
The call to 'shell-command will finish after the process is done (compression is complete).

Related

rename all files of a specific type in a directory

I am trying to use bash to rename all .txt files in a directory that match a specific pattern. My two attempts below have removed the files from the directory and threw an error. Thank you :)
input
16-0000_File-A_variant_strandbias_readcount.vcf.hg19_multianno_dbremoved_removed_final_index_inheritence_import.txt
16-0002_File-B_variant_strandbias_readcount.vcf.hg19_multianno_dbremoved_removed_final_index_inheritence_import.txt
desired output
16-0000_File-A_multianno.txt
16-0002_File-B_multianno.txt
Bash attempt 1 this removes the files from the directory
for f in /home/cmccabe/Desktop/test/vcf/overall/annovar/*_classify.txt ; do
# Grab file prefix.
p=${f%%_*_}
bname=`basename $f`
pref=${bname%%.txt}
mv "$f" ${p}_multianno.txt
done
Bash attempt 2 Substitution replacement not terminated at (eval 1) line 1.
for f in /home/cmccabe/Desktop/test/vcf/overall/annovar/*_classify.txt ; do
# Grab file prefix.
p=${f%%_*_}
bname=`basename $f`
pref=${bname%%.txt}
rename -n 's/^$f/' *${p}_multianno.txt
done
You don't need a loop. rename alone can do this:
rename -n 's/(.*?_[^_]+).*/${1}_multianno.txt/g' /home/cmccabe/Desktop/test/vcf/overall/annovar/*_classify.txt
The meaning of the regular expression is roughly,
capture everything from the start until the 2nd _,
match the rest,
and replace with the captured prefix and append _multianno.txt
With the -n flag, this command will print what it would do without actually doing it.
When the output looks good, remove the -n and rerun.

Counter in bash script

I have a script that extracts filenames from an input file and is supposed to read each line (filename) and unzip the specified file, saving the unzipped content as individual files. However, I can't get my counter to work and just get all the unzipped files in one large file.
Input file contains a list:
ens/484/59/traj.pdb 0.001353
ens/263/39/traj.pdb 0.004178
ens/400/35/traj.pdb 0.004191
I'm using the regex /.*?/.*?/ to extract the file that I'd like to unzip and name each output{1..40}.pdb -- instead I get one output file: output1.pdb which contains all the contents of the 40 unzipped files.
My question is: how do I correct my counter in order to achieve the desired naming scheme?
#!/bin/bash
file="/home/input.txt"
grep -Po '/.*?/.*?/' $file > filenames.txt
i=$((i+1))
structures='filenames.txt'
while IFS= read line
do
gunzip -c 'ens'$line'traj.pdb.gz' >> 'output'$i'.pdb'
done <"$structures"
rm "$structures"
file="/home/input.txt"
grep -Po '/.*?/.*?/' $file > filenames.txt
structures='filenames.txt'
i=1
while IFS= read "line"
do
gunzip -c 'ens'$line'traj.pdb.gz' >> 'output'$i'.pdb'
i=$(expr $i + 1)
done <$structures
rm $structures
couple of logical mistakes, the counter has to be fined as one out of the while loop and the counter +1 should be inside the loop, also for the counter to work you have to use expr, in this case i made the counter start from 1, so the first entry will get this value. Also on the parameter for the while loop i dont really understand what you are doing, if it works as you have it then cool or else use a test statement after while and before the parameters.

How to output filenames in shell?

Ive written the following piece of code to print the filenames of a directory in output. The directory is dir1 and the filenames are L1, L2, L3, ..,L512
#!/bin/bash
TOP=`pwd`
for file in "$TOP/dir1"/*; do
echo "$file"
done
exit
But instead of printing just the filenames (L1,L2,..), it outputs the whole path corresponding to each file. How could I change it to only receive the filenames at output?
Use the basename command:
for file in "$TOP/dir1"/*; do
basename "$file"
done

ksh script for existence of file

Always i get "Source file not readable or exists, please check the file " for the below code. I use cygwin in my windows machine to run the script. I am getting the same message even when the file is present in the location. How can i get more details as why the file is not readable.
#!/bin/ksh
#
# Scanning source file for existance and readable
file_loc="abc.xml"
if [ -f "$file_loc" -a -r "$file_loc"]
then
print "Source file read.\n"
else
print "Source file not readable or exists, please check the file $file_loc.\n"
fi
A space before the closing bracket is needed:
if [ -f "$file_loc" -a -r "$file_loc" ]
file_loc="abc.xml" && (< ${file_loc:?})
is an alternative check. An advantage is that it returns different messages for different errors; we let the shell do all the work.
How is this constructed? This single line can trigger at least three different messages:
The ${ varname :? optional message } syntax will check for undefined variables,
which can signal a typo in the variable name.
(< ${file_lo:?} )
-bash: file_lo: parameter null or not set
(< filename ) will just attempt to open and close the file.
$ (< nonesuch ) && echo ok
-bash: nonesuch: No such file or directory
$ (< /etc/shadow ) && echo ok
-bash: /etc/shadow: Permission denied

Does Chicken Scheme have an equivalent to Perl's $0?

How can I reliably get the script name in Chicken Scheme?
It seems that -ss eats up the script name, so it's not visible unless I use dot slash to run my scripts.
scriptedmain.scm:
#!/usr/bin/env csi -q
(display (command-line-arguments))
(display "\n")
(exit)
Trace:
$ ./scriptedmain.scm
(-q ./scriptedmain.scm)
wonko:Desktop andrew$ csi -ss scriptedmain.scm
()
This is a late response, so may not be of use to the original poster. But to any others who may come across this question, the simple answer is to use the parameter:
(program-name)
This should return the correct name for all situations. Docs here.
(argv) should do the job. Example:
#!/usr/local/bin/csi -script
(display (argv)) (newline) (exit)
prints (/usr/local/bin/csi -script ./test.scm)
scriptedmain.scm will run (main) and print the program name in the following cases:
Run from the interpreter:
csi -ss scriptedmain.scm
Run from the interpreter using shebangs:
./scriptedmain.scm
Compiled:
csc -o scriptedmain scriptedmain.scm
./scriptedmain
Added to GitHub.
#!/bin/sh
#|
exec csi -ss $0 ${1+"$#"}
exit
|#
(define (main)
(display (format "Program: ~a\n" (program-name)))
(exit))
(if (not (equal? (program-name) "csi"))
(main))

Resources