In the below bash I am trying to copy the only text file (always only one) in /home/cmccabe/Desktop/list/QC/metrics.txt and rename each of the 3 text files according to /home/cmccabe/Desktop/test/list.txt using lines 3, 4 ,5 . This format (that is list.txt) is always 5 lines. Thank you :).
/home/cmccabe/Desktop/test/list.txt
analysis done using v1.5 by cmccabe at 02/08/17 12:19:08 PM
patients analyzed:
00-0000_Last-First
11-1111_LastName-FirstName
22-2222_LastLastName-FirstFirstName
/home/cmccabe/Desktop/list/QC (always a single text file with data in it)
metrics.txt
linesToSkip=2
{
for ((i=$linesToSkip;i--;)) ;do
read
done
files=( /home/cmccabe/Desktop/list/QC/metrics.txt )
i=0
while read -r new_name; do
mv "${files[$i]}" "$new_name"
(( i++ ))
}
done < /home/cmccabe/Desktop/test/list.txt
It uses sed to get the whole file from after the LinesToSkip value. It also assumes that your list of files to rename is a white-space and/or row separated input file.
You may prefer to increment the counter in a different way, but the principle is the same.
As long as you're using bash (or a 1993 or later version of ksh ) and not just restricting yourself to POSIX required features and assuming that the file /home/cmccabe/Desktop/list/QC/metrics.txt contains the names of the files you want to move on the 1st three lines of that file (rather than being the name of a file that you want to copy to three other files), I'd be tempted to replace:
linesToSkip=2
{
for ((i=$linesToSkip;i--;)) ;do
read
done
files=( /home/cmccabe/Desktop/list/QC/metrics.txt )
i=0
while read -r new_name; do
mv "${files[$i]}" "$new_name"
(( i++ ))
}
done < /home/cmccabe/Desktop/test/list.txt
with:
linesToSkip=2
{ for((i = 1; i <= linesToSkip; i++))
do read
done
while read -r new_name && read -ru4 old_name
do mv "$old_name" "$new_name"
done
} < /home/cmccabe/Desktop/test/list.txt 4< /home/cmccabe/Desktop/list/QC/metrics.txt
Hi Robin,
Would I mind? Absolutely not! If you learn something from one of my posts, I hope you (and other readers) will learn from it and be able to use it in scripts you write. That is why I post in this forum.
@Don Cragun
I am trying to understand your code and thought I did but after it executes there is no output. I only modified the last line as I thought that was why there was no output, but it appears I was mistaken. I also tried to add the "_" (in bold). Thank you :).
linesToSkip=2 # skip lines 1 and 2
{ for((i = 1; i <= linesToSkip; i++)) # start at line 3
do read # read lines 3,4,5
done # stop
while read -r new_name && %s\"_"\n && read -ru4 old_name # read metrics.txt in variable
do mv "$old_name" "$new_name" copy orignal metrics.txt 3 times
done # stop
} < /home/cmccabe/Desktop/QC/test/metrics.txt 4< /home/cmccabe/Desktop/QC/analysis.txt # rename each metrics.txt using lines 3,4,5 of analysis.txt
/home/cmccabe/Desktop/QC/test/metrics.txt - tab-delimeted, always two lines - this is the file that is copied 3 times and renamed always using lines 3,4,5 of /home/cmccabe/Desktop/QC/analysis.txt
R_Index ISP Loading Pre-Enrichment Total Reads Read Length Key Signal Usable Sequence Enrichment Polyclonal Low Quality Test Fragment Aligned Bases Unaligned Bases Exception
1 89 . 78402052 201 77 61 98.6 29.2 10.4 79 98.8 1.2
/home/cmccabe/Desktop/QC/analysis.txt
analysis done using v1.5 by cmccabe at 02/08/17 12:19:08 PM
patients analyzed:
00-0000_Last-First
11-1111_LastName-FirstName
22-2222_LastLastName-FirstFirstName
I sincerely apologize for misleading you with my script. I paid too much attention to the code sample you provided in post #1 in this thread and not enough attention to the English description (which I found confusing). The description talks about copying files (and wasn't clear whether there was one file being copied or one file that contained the names of files to be copied), while your code was moving files whose source file names seemed to appear in one file and whose destination names seemed to appear in a second file. The fact that your code was moving (using mv ) and not copying (using cp ) seemed to confirm that there were three source files instead of one. (If there is only one source file, the last two copies will obviously fail since you're using mv instead of cp !)
If you have a single source file, and you're reading a destination name from a file, but you don't want the name of that destination file to be the name you read from the file; you need to clearly explain the transformation that is supposed to take place. (There is nothing in any of your code that makes any attempt to modify the names read from the file. And, I haven't found anything in your descriptions that talks about modifying the names found in the file other than confusing examples that don't clearly explain where the names are coming from.)
The code that you showed us (that you said produces no output) should be producing a diagnostic message because it is trying to invoke a utility named
%s"_\n && read -ru4 old_name # read metrics.txt in variable
do mv old_name copy orignal metrics.txt 3 times
done # stop... ... ...
continuing on until a matching double-quote character ( " ) is found to match the double-quote character that appears at the end of $new_name" . Note that the new_name variable is not defined in your modification to my code (and therefore, the expansion $new_name expands to an empty string).
Please give us a clearer description of what you are trying to do.
The metrics.txt in /home/cmccabe/Desktop/QC/test is the file that is copied 3 times. Each one of of those 3 copies is then renamed using lines 3,4,5 in analysis.txt in /home/cmccabe/Desktop/QC with a _ in the name.
So in /home/cmccabe/Desktop/QC/test before the code is executed there is one metrics.txt . Then after the code is executed there are 3 metrics.txt that are renamed using the analysis.txt , lines 3,4,5.
The format of analysis.txt is always the same, that is it is always five lines with the first two being skipped with lines 3,4,5 having the rename lines in them.
analysis.txt in /home/cmccabe/Desktop/QC
status: complete
id names:
00-0000_Last-First
01-0101_LastN-FirstN
02-0202_La-Fi
metrics.txt in /home/cmccabe/Desktop/QC/test , then code is executed:
According to the above description, we are supposed to start with two files in a directory: metrics.txt and analysis.txt . Then we are supposed to create three more copies of metrics.txt also named metrics.txt and then we are supposed to rename three of those four file and end up with four files: 00-0000_Last-First_metrics.txt , 11-1111_LastName-FirstName_metrics.txt , 22-2222_LastLastName-FirstFirstName_metrics.txt , and analysis.txt .
Doing it in this sequence is impossible because you can never have two files in one directory with the same name. We can copy a file three times to new files with different names. But, if we do that, the original metrics.txt file would still be there. (But your description above says it should not be there.) So, is what you really want correctly described by saying that you want to rename metrics.txt to be the filename derives from the third line in analysis.txt and then you want to copy that file to two more files with filenames derived from the 4th and 5th lines in analysis.txt ?
Why do you need three or four copies of the same text? Why not just link the three new names to metrics.txt using an ln command (or tell whatever program will be reading these files that the name of the file they should read is just metrics.txt )?
The metrics.txt in / home/cmccabe/Desktop/QC/test is saved as 3 separate .txt files. Each one of of those 3 .txt files is then renamed using lines 3,4,5 in analysis.txt in /home/cmccabe/Desktop/QC with a _ in the name.
Another process that is used is expecting 3 files in home/cmccabe/Desktop/QC/test to function properly, so this is a temporary solution to that (until that process can be re-written). Thank you very much :).
home/cmccabe/Desktop/QC/test
metrics1.txt
metrics2.txt
metrics3.txt
analysis.txt in /home/cmccabe/Desktop/QC
status: complete
id names:
00-0000_Last-First
01-0101_LastN-FirstN
02-0202_La-Fi
desired output in home/cmccabe/Desktop/QC/test after the script executes
Extraction of base filenames, then tack on the suffix:
#!/usr/bin/env bash
# @(#) s1 Demonstrate replicate file to files determined by list.
# Utility functions: print-as-echo, print-line-with-visual-space, debug.
# export PATH="/usr/local/bin:/usr/bin:/bin"
LC_ALL=C ; LANG=C ; export LC_ALL LANG
pe() { for _i;do printf "%s" "$_i";done; printf "\n"; }
pl() { pe;pe "-----" ;pe "$*"; }
em() { pe "$*" >&2 ; }
db() { ( printf " db, ";for _i;do printf "%s" "$_i";done;printf "\n" ) >&2 ; }
db() { : ; }
C=$HOME/bin/context && [ -f $C ] && $C sed cp
pl " Input data files data1, data2:"
head data[12]
pl " Results:"
for file in $( sed -n '3,5p' data2 )
do
echo cp data1 ${file}_metrics.txt
done
exit 0
producing:
$ ./s1
Environment: LC_ALL = C, LANG = C
(Versions displayed with local utility "version")
OS, ker|rel, machine: Linux, 3.16.0-4-amd64, x86_64
Distribution : Debian 8.7 (jessie)
bash GNU bash 4.3.30
sed (GNU sed) 4.2.2
cp (GNU coreutils) 8.23
-----
Input data files data1, data2:
==> data1 <==
Some text that is not important to the process.
==> data2 <==
analysis done using v1.5 by cmccabe at 02/08/17 12:19:08 PM
patients analyzed:
00-0000_Last-First
11-1111_LastName-FirstName
22-2222_LastLastName-FirstFirstName
-----
Results:
cp data1 00-0000_Last-First_metrics.txt
cp data1 11-1111_LastName-FirstName_metrics.txt
cp data1 22-2222_LastLastName-FirstFirstName_metrics.txt
Remove the final echo when satisfied that the filenames are correct.